<!DOCTYPE html><html><head><meta charset="utf-8"><title>Angular - 属性型指令</title><base href="/"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="search" type="application/opensearchdescription+xml" href="assets/opensearch.xml"><link rel="icon" type="image/x-icon" href="assets/images/favicons/favicon.ico"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-32x32.png" sizes="32x32"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-194x194.png" sizes="194x194"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-96x96.png" sizes="96x96"><link rel="icon" type="image/png" href="assets/images/favicons/favicon-16x16.png" sizes="16x16"><link rel="apple-touch-icon" sizes="144x144" href="assets/images/favicons/favicon-144x144.png"><link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/images/favicons/favicon-144x144.png"><link href="assets/fonts/Material_Icons.css" rel="stylesheet"><link href="assets/fonts/Droid_Sans_Mono.css" rel="stylesheet"><link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"><link rel="manifest" href="pwa-manifest.json"><meta name="theme-color" content="#1976d2"><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="translucent"><script async="" src="assets/js/analytics.js"></script><script>!function(e,a,n,t,s,c,g){e.GoogleAnalyticsObject=s,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(n),g=a.getElementsByTagName(n)[0],c.async=1,c.src="assets/js/analytics.js",~e.name.indexOf("NG_DEFER_BOOTSTRAP")||g.parentNode.insertBefore(c,g)}(window,document,"script",0,"ga")</script><script>window.onerror=function(){ga("send","exception",{exDescription:function(e,r,n,a,c){var l;e=e.replace(/^Error: /,""),l=c?c.stack.replace(/^Error: /,"").replace(e+"\n","").replace(/^ +/gm,"").replace(/^at /gm,"").replace(/(?: \(|@)http.+\/([^/)]+)\)?(?:\n|$)/gm,"@$1\n").replace(/ *\(eval code(:\d+:\d+)\)(?:\n|$)/gm,"@???$1\n"):r+":"+(n=n||"?")+":"+(a=a||"?");return(e+"\n"+l).substr(0,150)}.apply(null,arguments),exFatal:!0})}</script><script nomodule="" src="generated/ie-polyfills.min.js"></script><link rel="stylesheet" href="styles.10ba6936decaea45eabb.css"><style>@media screen and (-ms-high-contrast:active){.mat-toolbar{outline:solid 1px}}.mat-toolbar-row,.mat-toolbar-single-row{display:flex;box-sizing:border-box;padding:0 16px;width:100%;flex-direction:row;align-items:center;white-space:nowrap}.mat-toolbar-multiple-rows{display:flex;box-sizing:border-box;flex-direction:column;width:100%}.mat-toolbar-multiple-rows{min-height:64px}.mat-toolbar-row,.mat-toolbar-single-row{height:64px}@media (max-width:599px){.mat-toolbar-multiple-rows{min-height:56px}.mat-toolbar-row,.mat-toolbar-single-row{height:56px}}</style><style>.mat-icon{background-repeat:no-repeat;display:inline-block;fill:currentColor;height:24px;width:24px}.mat-icon.mat-icon-inline{font-size:inherit;height:inherit;line-height:inherit;width:inherit}[dir=rtl] .mat-icon-rtl-mirror{transform:scale(-1,1)}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon{display:block}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button .mat-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button .mat-icon{margin:auto}</style><style>.mat-button .mat-button-focus-overlay,.mat-icon-button .mat-button-focus-overlay{opacity:0}.mat-button:hover .mat-button-focus-overlay,.mat-stroked-button:hover .mat-button-focus-overlay{opacity:.04}@media (hover:none){.mat-button:hover .mat-button-focus-overlay,.mat-stroked-button:hover .mat-button-focus-overlay{opacity:0}}.mat-button,.mat-flat-button,.mat-icon-button,.mat-stroked-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible}.mat-button::-moz-focus-inner,.mat-flat-button::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-stroked-button::-moz-focus-inner{border:0}.mat-button[disabled],.mat-flat-button[disabled],.mat-icon-button[disabled],.mat-stroked-button[disabled]{cursor:default}.mat-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-button.cdk-program-focused .mat-button-focus-overlay,.mat-flat-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-flat-button.cdk-program-focused .mat-button-focus-overlay,.mat-icon-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-icon-button.cdk-program-focused .mat-button-focus-overlay,.mat-stroked-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-stroked-button.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-button::-moz-focus-inner,.mat-flat-button::-moz-focus-inner,.mat-icon-button::-moz-focus-inner,.mat-stroked-button::-moz-focus-inner{border:0}.mat-raised-button{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1)}.mat-raised-button::-moz-focus-inner{border:0}.mat-raised-button[disabled]{cursor:default}.mat-raised-button.cdk-keyboard-focused .mat-button-focus-overlay,.mat-raised-button.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-raised-button::-moz-focus-inner{border:0}._mat-animation-noopable.mat-raised-button{transition:none;animation:none}.mat-stroked-button{border:1px solid currentColor;padding:0 15px;line-height:34px}.mat-fab{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);min-width:0;border-radius:50%;width:56px;height:56px;padding:0;flex-shrink:0}.mat-fab::-moz-focus-inner{border:0}.mat-fab[disabled]{cursor:default}.mat-fab.cdk-keyboard-focused .mat-button-focus-overlay,.mat-fab.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-fab::-moz-focus-inner{border:0}._mat-animation-noopable.mat-fab{transition:none;animation:none}.mat-fab .mat-button-wrapper{padding:16px 0;display:inline-block;line-height:24px}.mat-mini-fab{box-sizing:border-box;position:relative;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer;outline:0;border:none;-webkit-tap-highlight-color:transparent;display:inline-block;white-space:nowrap;text-decoration:none;vertical-align:baseline;text-align:center;margin:0;min-width:64px;line-height:36px;padding:0 16px;border-radius:4px;overflow:visible;transform:translate3d(0,0,0);transition:background .4s cubic-bezier(.25,.8,.25,1),box-shadow 280ms cubic-bezier(.4,0,.2,1);min-width:0;border-radius:50%;width:40px;height:40px;padding:0;flex-shrink:0}.mat-mini-fab::-moz-focus-inner{border:0}.mat-mini-fab[disabled]{cursor:default}.mat-mini-fab.cdk-keyboard-focused .mat-button-focus-overlay,.mat-mini-fab.cdk-program-focused .mat-button-focus-overlay{opacity:.12}.mat-mini-fab::-moz-focus-inner{border:0}._mat-animation-noopable.mat-mini-fab{transition:none;animation:none}.mat-mini-fab .mat-button-wrapper{padding:8px 0;display:inline-block;line-height:24px}.mat-icon-button{padding:0;min-width:0;width:40px;height:40px;flex-shrink:0;line-height:40px;border-radius:50%}.mat-icon-button .mat-icon,.mat-icon-button i{line-height:24px}.mat-button-focus-overlay,.mat-button-ripple.mat-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none;border-radius:inherit}.mat-button-focus-overlay{border-radius:inherit;opacity:0;transition:opacity .2s cubic-bezier(.35,0,.25,1),background-color .2s cubic-bezier(.35,0,.25,1)}._mat-animation-noopable .mat-button-focus-overlay{transition:none}@media screen and (-ms-high-contrast:active){.mat-button-focus-overlay{background-color:rgba(255,255,255,.5)}}.mat-button-ripple-round{border-radius:50%;z-index:1}.mat-button .mat-button-wrapper>*,.mat-fab .mat-button-wrapper>*,.mat-flat-button .mat-button-wrapper>*,.mat-icon-button .mat-button-wrapper>*,.mat-mini-fab .mat-button-wrapper>*,.mat-raised-button .mat-button-wrapper>*,.mat-stroked-button .mat-button-wrapper>*{vertical-align:middle}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button{display:block;font-size:inherit;width:2.5em;height:2.5em}@media screen and (-ms-high-contrast:active){.mat-button,.mat-fab,.mat-flat-button,.mat-icon-button,.mat-mini-fab,.mat-raised-button{outline:solid 1px}}</style><style>.mat-drawer-container{position:relative;z-index:1;box-sizing:border-box;-webkit-overflow-scrolling:touch;display:block;overflow:hidden}.mat-drawer-container[fullscreen]{top:0;left:0;right:0;bottom:0;position:absolute}.mat-drawer-container[fullscreen].mat-drawer-opened{overflow:hidden}.mat-drawer-container.mat-drawer-container-explicit-backdrop .mat-drawer-side{z-index:3}.mat-drawer-container.ng-animate-disabled .mat-drawer-backdrop,.mat-drawer-container.ng-animate-disabled .mat-drawer-content,.ng-animate-disabled .mat-drawer-container .mat-drawer-backdrop,.ng-animate-disabled .mat-drawer-container .mat-drawer-content{transition:none}.mat-drawer-backdrop{top:0;left:0;right:0;bottom:0;position:absolute;display:block;z-index:3;visibility:hidden}.mat-drawer-backdrop.mat-drawer-shown{visibility:visible}.mat-drawer-transition .mat-drawer-backdrop{transition-duration:.4s;transition-timing-function:cubic-bezier(.25,.8,.25,1);transition-property:background-color,visibility}@media screen and (-ms-high-contrast:active){.mat-drawer-backdrop{opacity:.5}}.mat-drawer-content{position:relative;z-index:1;display:block;height:100%;overflow:auto}.mat-drawer-transition .mat-drawer-content{transition-duration:.4s;transition-timing-function:cubic-bezier(.25,.8,.25,1);transition-property:transform,margin-left,margin-right}.mat-drawer{position:relative;z-index:4;display:block;position:absolute;top:0;bottom:0;z-index:3;outline:0;box-sizing:border-box;overflow-y:auto;transform:translate3d(-100%,0,0)}@media screen and (-ms-high-contrast:active){.mat-drawer,[dir=rtl] .mat-drawer.mat-drawer-end{border-right:solid 1px currentColor}}@media screen and (-ms-high-contrast:active){.mat-drawer.mat-drawer-end,[dir=rtl] .mat-drawer{border-left:solid 1px currentColor;border-right:none}}.mat-drawer.mat-drawer-side{z-index:2}.mat-drawer.mat-drawer-end{right:0;transform:translate3d(100%,0,0)}[dir=rtl] .mat-drawer{transform:translate3d(100%,0,0)}[dir=rtl] .mat-drawer.mat-drawer-end{left:0;right:auto;transform:translate3d(-100%,0,0)}.mat-drawer-inner-container{width:100%;height:100%;overflow:auto;-webkit-overflow-scrolling:touch}.mat-sidenav-fixed{position:fixed}</style><style>.nav-link.highlight[_ngcontent-c5]{color:#ff0}</style><script charset="utf-8" src="toc-toc-module-ngfactory.36694c537d7ff0b2c081.js"></script><script charset="utf-8" src="default~code-code-example-module-ngfactory~code-code-tabs-module-ngfactory~getting-started-ng-for-ng~82f414e5.c64b8abba8f3b7168616.js"></script><script charset="utf-8" src="default~code-code-example-module-ngfactory~code-code-tabs-module-ngfactory.98830c4eaea3268880de.js"></script><script charset="utf-8" src="code-code-example-module-ngfactory.bb14a03c7095ffd0e7bd.js"></script><script charset="utf-8" src="code-code-tabs-module-ngfactory.e688ffb25bac166802a3.js"></script><script charset="utf-8" src="live-example-live-example-module-ngfactory.fef451c7b16613f97732.js"></script><style>.mat-progress-bar{display:block;height:4px;overflow:hidden;position:relative;transition:opacity 250ms linear;width:100%}._mat-animation-noopable.mat-progress-bar{transition:none;animation:none}.mat-progress-bar .mat-progress-bar-element,.mat-progress-bar .mat-progress-bar-fill::after{height:100%;position:absolute;width:100%}.mat-progress-bar .mat-progress-bar-background{width:calc(100% + 10px)}@media screen and (-ms-high-contrast:active){.mat-progress-bar .mat-progress-bar-background{display:none}}.mat-progress-bar .mat-progress-bar-buffer{transform-origin:top left;transition:transform 250ms ease}@media screen and (-ms-high-contrast:active){.mat-progress-bar .mat-progress-bar-buffer{border-top:solid 5px;opacity:.5}}.mat-progress-bar .mat-progress-bar-secondary{display:none}.mat-progress-bar .mat-progress-bar-fill{animation:none;transform-origin:top left;transition:transform 250ms ease}@media screen and (-ms-high-contrast:active){.mat-progress-bar .mat-progress-bar-fill{border-top:solid 4px}}.mat-progress-bar .mat-progress-bar-fill::after{animation:none;content:'';display:inline-block;left:0}.mat-progress-bar[dir=rtl],[dir=rtl] .mat-progress-bar{transform:rotateY(180deg)}.mat-progress-bar[mode=query]{transform:rotateZ(180deg)}.mat-progress-bar[mode=query][dir=rtl],[dir=rtl] .mat-progress-bar[mode=query]{transform:rotateZ(180deg) rotateY(180deg)}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-fill,.mat-progress-bar[mode=query] .mat-progress-bar-fill{transition:none}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-primary,.mat-progress-bar[mode=query] .mat-progress-bar-primary{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-primary-indeterminate-translate 2s infinite linear;left:-145.166611%}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-primary.mat-progress-bar-fill::after,.mat-progress-bar[mode=query] .mat-progress-bar-primary.mat-progress-bar-fill::after{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-primary-indeterminate-scale 2s infinite linear}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-secondary,.mat-progress-bar[mode=query] .mat-progress-bar-secondary{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-secondary-indeterminate-translate 2s infinite linear;left:-54.888891%;display:block}.mat-progress-bar[mode=indeterminate] .mat-progress-bar-secondary.mat-progress-bar-fill::after,.mat-progress-bar[mode=query] .mat-progress-bar-secondary.mat-progress-bar-fill::after{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-secondary-indeterminate-scale 2s infinite linear}.mat-progress-bar[mode=buffer] .mat-progress-bar-background{-webkit-backface-visibility:hidden;backface-visibility:hidden;animation:mat-progress-bar-background-scroll 250ms infinite linear;display:block}.mat-progress-bar._mat-animation-noopable .mat-progress-bar-background,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-buffer,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-fill,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-fill::after,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-primary,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-primary.mat-progress-bar-fill::after,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-secondary,.mat-progress-bar._mat-animation-noopable .mat-progress-bar-secondary.mat-progress-bar-fill::after{animation:none;transition:none}@keyframes mat-progress-bar-primary-indeterminate-translate{0%{transform:translateX(0)}20%{animation-timing-function:cubic-bezier(.5,0,.70173,.49582);transform:translateX(0)}59.15%{animation-timing-function:cubic-bezier(.30244,.38135,.55,.95635);transform:translateX(83.67142%)}100%{transform:translateX(200.61106%)}}@keyframes mat-progress-bar-primary-indeterminate-scale{0%{transform:scaleX(.08)}36.65%{animation-timing-function:cubic-bezier(.33473,.12482,.78584,1);transform:scaleX(.08)}69.15%{animation-timing-function:cubic-bezier(.06,.11,.6,1);transform:scaleX(.66148)}100%{transform:scaleX(.08)}}@keyframes mat-progress-bar-secondary-indeterminate-translate{0%{animation-timing-function:cubic-bezier(.15,0,.51506,.40969);transform:translateX(0)}25%{animation-timing-function:cubic-bezier(.31033,.28406,.8,.73371);transform:translateX(37.65191%)}48.35%{animation-timing-function:cubic-bezier(.4,.62704,.6,.90203);transform:translateX(84.38617%)}100%{transform:translateX(160.27778%)}}@keyframes mat-progress-bar-secondary-indeterminate-scale{0%{animation-timing-function:cubic-bezier(.15,0,.51506,.40969);transform:scaleX(.08)}19.15%{animation-timing-function:cubic-bezier(.31033,.28406,.8,.73371);transform:scaleX(.4571)}44.15%{animation-timing-function:cubic-bezier(.4,.62704,.6,.90203);transform:scaleX(.72796)}100%{transform:scaleX(.08)}}@keyframes mat-progress-bar-background-scroll{to{transform:translateX(-8px)}}</style><script charset="utf-8" src="21.d3ebf64aa7b6d3a4b8f6.js"></script><style>.mat-card{transition:box-shadow 280ms cubic-bezier(.4,0,.2,1);display:block;position:relative;padding:16px;border-radius:4px}.mat-card .mat-divider-horizontal{position:absolute;left:0;width:100%}[dir=rtl] .mat-card .mat-divider-horizontal{left:auto;right:0}.mat-card .mat-divider-horizontal.mat-divider-inset{position:static;margin:0}[dir=rtl] .mat-card .mat-divider-horizontal.mat-divider-inset{margin-right:0}@media screen and (-ms-high-contrast:active){.mat-card{outline:solid 1px}}.mat-card-actions,.mat-card-content,.mat-card-subtitle{display:block;margin-bottom:16px}.mat-card-title{display:block;margin-bottom:8px}.mat-card-actions{margin-left:-8px;margin-right:-8px;padding:8px 0}.mat-card-actions-align-end{display:flex;justify-content:flex-end}.mat-card-image{width:calc(100% + 32px);margin:0 -16px 16px -16px}.mat-card-footer{display:block;margin:0 -16px -16px -16px}.mat-card-actions .mat-button,.mat-card-actions .mat-raised-button{margin:0 8px}.mat-card-header{display:flex;flex-direction:row}.mat-card-header .mat-card-title{margin-bottom:12px}.mat-card-header-text{margin:0 16px}.mat-card-avatar{height:40px;width:40px;border-radius:50%;flex-shrink:0;object-fit:cover}.mat-card-title-group{display:flex;justify-content:space-between}.mat-card-sm-image{width:80px;height:80px}.mat-card-md-image{width:112px;height:112px}.mat-card-lg-image{width:152px;height:152px}.mat-card-xl-image{width:240px;height:240px;margin:-8px}.mat-card-title-group>.mat-card-xl-image{margin:-8px 0 8px 0}@media (max-width:599px){.mat-card-title-group{margin:0}.mat-card-xl-image{margin-left:0;margin-right:0}}.mat-card-content>:first-child,.mat-card>:first-child{margin-top:0}.mat-card-content>:last-child:not(.mat-card-footer),.mat-card>:last-child:not(.mat-card-footer){margin-bottom:0}.mat-card-image:first-child{margin-top:-16px;border-top-left-radius:inherit;border-top-right-radius:inherit}.mat-card>.mat-card-actions:last-child{margin-bottom:-8px;padding-bottom:0}.mat-card-actions .mat-button:first-child,.mat-card-actions .mat-raised-button:first-child{margin-left:0;margin-right:0}.mat-card-title{margin-bottom:8px}.mat-card-subtitle:not(:first-child),.mat-card-title:not(:first-child){margin-top:-4px}.mat-card-header .mat-card-subtitle:not(:first-child){margin-top:-8px}.mat-card>.mat-card-xl-image:first-child{margin-top:-8px}.mat-card>.mat-card-xl-image:last-child{margin-bottom:-8px}</style><style>.mat-tab-group{display:flex;flex-direction:column}.mat-tab-group.mat-tab-group-inverted-header{flex-direction:column-reverse}.mat-tab-label{height:48px;padding:0 24px;cursor:pointer;box-sizing:border-box;opacity:.6;min-width:160px;text-align:center;display:inline-flex;justify-content:center;align-items:center;white-space:nowrap;position:relative}.mat-tab-label:focus{outline:0}.mat-tab-label:focus:not(.mat-tab-disabled){opacity:1}@media screen and (-ms-high-contrast:active){.mat-tab-label:focus{outline:dotted 2px}}.mat-tab-label.mat-tab-disabled{cursor:default}@media screen and (-ms-high-contrast:active){.mat-tab-label.mat-tab-disabled{opacity:.5}}.mat-tab-label .mat-tab-label-content{display:inline-flex;justify-content:center;align-items:center;white-space:nowrap}@media screen and (-ms-high-contrast:active){.mat-tab-label{opacity:1}}@media (max-width:599px){.mat-tab-label{padding:0 12px}}@media (max-width:959px){.mat-tab-label{padding:0 12px}}.mat-tab-group[mat-stretch-tabs]>.mat-tab-header .mat-tab-label{flex-basis:0;flex-grow:1}.mat-tab-body-wrapper{position:relative;overflow:hidden;display:flex;transition:height .5s cubic-bezier(.35,0,.25,1)}.mat-tab-body{top:0;left:0;right:0;bottom:0;position:absolute;display:block;overflow:hidden;flex-basis:100%}.mat-tab-body.mat-tab-body-active{position:relative;overflow-x:hidden;overflow-y:auto;z-index:1;flex-grow:1}.mat-tab-group.mat-tab-group-dynamic-height .mat-tab-body.mat-tab-body-active{overflow-y:hidden}</style><style>.mat-tab-header{display:flex;overflow:hidden;position:relative;flex-shrink:0}.mat-tab-label{height:48px;padding:0 24px;cursor:pointer;box-sizing:border-box;opacity:.6;min-width:160px;text-align:center;display:inline-flex;justify-content:center;align-items:center;white-space:nowrap;position:relative}.mat-tab-label:focus{outline:0}.mat-tab-label:focus:not(.mat-tab-disabled){opacity:1}@media screen and (-ms-high-contrast:active){.mat-tab-label:focus{outline:dotted 2px}}.mat-tab-label.mat-tab-disabled{cursor:default}@media screen and (-ms-high-contrast:active){.mat-tab-label.mat-tab-disabled{opacity:.5}}.mat-tab-label .mat-tab-label-content{display:inline-flex;justify-content:center;align-items:center;white-space:nowrap}@media screen and (-ms-high-contrast:active){.mat-tab-label{opacity:1}}@media (max-width:599px){.mat-tab-label{min-width:72px}}.mat-ink-bar{position:absolute;bottom:0;height:2px;transition:.5s cubic-bezier(.35,0,.25,1)}.mat-tab-group-inverted-header .mat-ink-bar{bottom:auto;top:0}@media screen and (-ms-high-contrast:active){.mat-ink-bar{outline:solid 2px;height:0}}.mat-tab-header-pagination{position:relative;display:none;justify-content:center;align-items:center;min-width:32px;cursor:pointer;z-index:2}.mat-tab-header-pagination-controls-enabled .mat-tab-header-pagination{display:flex}.mat-tab-header-pagination-before,.mat-tab-header-rtl .mat-tab-header-pagination-after{padding-left:4px}.mat-tab-header-pagination-before .mat-tab-header-pagination-chevron,.mat-tab-header-rtl .mat-tab-header-pagination-after .mat-tab-header-pagination-chevron{transform:rotate(-135deg)}.mat-tab-header-pagination-after,.mat-tab-header-rtl .mat-tab-header-pagination-before{padding-right:4px}.mat-tab-header-pagination-after .mat-tab-header-pagination-chevron,.mat-tab-header-rtl .mat-tab-header-pagination-before .mat-tab-header-pagination-chevron{transform:rotate(45deg)}.mat-tab-header-pagination-chevron{border-style:solid;border-width:2px 2px 0 0;content:'';height:8px;width:8px}.mat-tab-header-pagination-disabled{box-shadow:none;cursor:default}.mat-tab-label-container{display:flex;flex-grow:1;overflow:hidden;z-index:1}.mat-tab-list{flex-grow:1;position:relative;transition:transform .5s cubic-bezier(.35,0,.25,1)}.mat-tab-labels{display:flex}[mat-align-tabs=center] .mat-tab-labels{justify-content:center}[mat-align-tabs=end] .mat-tab-labels{justify-content:flex-end}</style><style>.mat-tab-body-content{height:100%;overflow:auto}.mat-tab-group-dynamic-height .mat-tab-body-content{overflow:hidden}</style></head><body><aio-shell ng-version="7.0.0" class="mode-stable sidenav-open page-guide-attribute-directives folder-guide view-SideNav aio-notification-show"><div id="top-of-page"></div><mat-toolbar class="app-toolbar no-print mat-toolbar mat-primary mat-toolbar-multiple-rows" color="primary"><mat-toolbar-row class="notification-container mat-toolbar-row"><aio-notification expirationdate="2019-03-01" notificationid="survey-february-2019" class="ng-tns-c2-0 ng-trigger ng-trigger-hideAnimation"><span class="content"><a href="http://bit.ly/angular-survey-2019" target="_blank"><mat-icon aria-label="Announcement" class="icon mat-icon" role="img" svgicon="insert_comment" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M20 2H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h14l4 4V4c0-1.1-.9-2-2-2zm-2 12H6v-2h12v2zm0-3H6V9h12v2zm0-3H6V6h12v2z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></mat-icon><span class="message"><b>填写这份《一分钟调查》</b>，帮我们（开发组）做得更好！</span><span class="action-button">去填写</span></a></span><button class="close-button mat-icon-button" aria-label="Close" mat-icon-button=""><span class="mat-button-wrapper"><mat-icon aria-label="Dismiss notification" class="mat-icon ng-tns-c2-0" role="img" svgicon="close" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path><path d="M0 0h24v24H0z" fill="none"></path></svg></mat-icon></span><div class="mat-button-ripple mat-ripple mat-button-ripple-round" matripple=""></div><div class="mat-button-focus-overlay"></div></button></aio-notification></mat-toolbar-row><mat-toolbar-row class="mat-toolbar-row"><button class="hamburger mat-button" mat-button="" title="Docs menu"><span class="mat-button-wrapper"><mat-icon class="mat-icon" role="img" svgicon="menu" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"></path></svg></mat-icon></span><div class="mat-button-ripple mat-ripple" matripple=""></div><div class="mat-button-focus-overlay"></div></button><a class="nav-link home" href="/"><img alt="Home" height="40" src="assets/images/logos/angular/logo-nav@2x.png" title="Home" width="150" class="ng-star-inserted"></a><aio-top-menu _nghost-c5="" class="ng-star-inserted"><ul _ngcontent-c5="" role="navigation"><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="features" title="特性"><span _ngcontent-c5="" class="nav-link-inner">特性</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="docs" title="文档"><span _ngcontent-c5="" class="nav-link-inner">文档</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="resources" title="资源"><span _ngcontent-c5="" class="nav-link-inner">资源</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="events" title="会议"><span _ngcontent-c5="" class="nav-link-inner">会议</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="https://blog.angular.io/" title="博客"><span _ngcontent-c5="" class="nav-link-inner">博客</span></a></li><li _ngcontent-c5="" class="ng-star-inserted"><a _ngcontent-c5="" class="nav-link" href="translations/cn/home" title="关于中文版"><span _ngcontent-c5="" class="nav-link-inner">关于中文版</span></a></li></ul></aio-top-menu><aio-search-box class="search-container"><input aria-label="search" placeholder="搜索" type="search"></aio-search-box><div class="toolbar-external-icons-container"><a aria-label="Angular on twitter" href="https://twitter.com/angular" title="Twitter"><mat-icon class="mat-icon" role="img" svgicon="logos:twitter" aria-hidden="true"><svg focusable="false" viewBox="0 0 50 59" xmlns="http://www.w3.org/2000/svg"><path d="M50,9.3c-1.8,0.8-3.8,1.4-5.9,1.6c2.1-1.3,3.7-3.3,4.5-5.7c-2,1.2-4.2,2-6.5,2.5c-1.9-2-4.5-3.2-7.5-3.2c-5.7,0-10.3,4.6-10.3,10.3c0,0.8,0.1,1.6,0.3,2.3C16.1,16.7,8.5,12.6,3.5,6.4c-0.9,1.5-1.4,3.3-1.4,5.2c0,3.6,1.8,6.7,4.6,8.5C5,20,3.4,19.6,2,18.8c0,0,0,0.1,0,0.1c0,5,3.5,9.1,8.2,10.1c-0.9,0.2-1.8,0.4-2.7,0.4c-0.7,0-1.3-0.1-1.9-0.2c1.3,4.1,5.1,7,9.6,7.1c-3.5,2.8-7.9,4.4-12.7,4.4c-0.8,0-1.6,0-2.4-0.1c4.5,2.9,9.9,4.6,15.7,4.6c18.9,0,29.2-15.6,29.2-29.2c0-0.4,0-0.9,0-1.3C46.9,13.2,48.6,11.4,50,9.3z"></path></svg></mat-icon></a><a aria-label="Angular on github" href="https://github.com/angular/angular" title="GitHub"><mat-icon class="mat-icon" role="img" svgicon="logos:github" aria-hidden="true"><svg focusable="false" viewBox="0 0 51.8 50.4" xmlns="http://www.w3.org/2000/svg"><path d="M25.9,0.2C11.8,0.2,0.3,11.7,0.3,25.8c0,11.3,7.3,20.9,17.5,24.3c1.3,0.2,1.7-0.6,1.7-1.2c0-0.6,0-2.6,0-4.8c-7.1,1.5-8.6-3-8.6-3c-1.2-3-2.8-3.7-2.8-3.7c-2.3-1.6,0.2-1.6,0.2-1.6c2.6,0.2,3.9,2.6,3.9,2.6c2.3,3.9,6,2.8,7.5,2.1c0.2-1.7,0.9-2.8,1.6-3.4c-5.7-0.6-11.7-2.8-11.7-12.7c0-2.8,1-5.1,2.6-6.9c-0.3-0.7-1.1-3.3,0.3-6.8c0,0,2.1-0.7,7,2.6c2-0.6,4.2-0.9,6.4-0.9c2.2,0,4.4,0.3,6.4,0.9c4.9-3.3,7-2.6,7-2.6c1.4,3.5,0.5,6.1,0.3,6.8c1.6,1.8,2.6,4.1,2.6,6.9c0,9.8-6,12-11.7,12.6c0.9,0.8,1.7,2.4,1.7,4.7c0,3.4,0,6.2,0,7c0,0.7,0.5,1.5,1.8,1.2c10.2-3.4,17.5-13,17.5-24.3C51.5,11.7,40.1,0.2,25.9,0.2z"></path></svg></mat-icon></a></div></mat-toolbar-row></mat-toolbar><mat-sidenav-container class="sidenav-container mat-drawer-container mat-sidenav-container mat-drawer-transition has-floating-toc" role="main"><div class="mat-drawer-backdrop ng-star-inserted"></div><div class="cdk-visually-hidden cdk-focus-trap-anchor"></div><mat-sidenav class="sidenav mat-drawer mat-sidenav ng-tns-c7-1 ng-trigger ng-trigger-transform mat-drawer-side ng-star-inserted" tabindex="-1" style="transform:none;visibility:visible"><div class="mat-drawer-inner-container"><aio-nav-menu><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="guide/quickstart" title="对 Angular 和 Angular CLI 基础知识的简短介绍" target="_self">快速上手</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="此《英雄指南》教程会带你用 TypeScript 一步步创建一个 Angular 应用。" aria-pressed="false">教程<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial" title="《英雄指南》教程简介" target="_self">简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt0" title="创建应用的外壳" target="_self">应用的“外壳”</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt1" title="第一部分：构建一个简单的英雄编辑器" target="_self">1. 英雄编辑器</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt2" title="第二部分：构建一个主从结构的页面，用于展现英雄列表。" target="_self">2. 显示英雄列表</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt3" title="第三部分：把主从结构的页面重构成多个组件。" target="_self">3. 主从组件</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt4" title="第四部分：创建一个可复用的服务来管理英雄数据。" target="_self">4. 服务</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt5" title="第五部分：添加 Angular 路由器，并且学习在视图之间导航。" target="_self">5. 路由</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="tutorial/toh-pt6" title="第六部分：通过 HTTP 来获取并保存英雄数据。" target="_self">6. HTTP</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 expanded selected ng-star-inserted" type="button" title="学习 Angular 的核心知识" aria-pressed="true">核心知识<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 expanded selected"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular 应用的基本构造块。" aria-pressed="false">架构<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture" title="Angular 应用的基本构造块" target="_self">架构概览</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-modules" title="关于模块。" target="_self">模块（NgModule）简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-components" title="关于组件、模板和视图。" target="_self">组件简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-services" title="关于服务与依赖注入。" target="_self">服务与 DI 简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/architecture-next-steps" title="学完基础知识之后……" target="_self">后续步骤</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 expanded selected ng-star-inserted" type="button" title="使用数据绑定构建动态视图" aria-pressed="true">组件与模板<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 expanded selected"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/displaying-data" title="属性绑定可以帮助应用把数据显示在界面上" target="_self">显示数据</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/template-syntax" title="学习如何写模板，以便借助数据绑定机制显示数据并响应事件。" target="_self">模板语法</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/user-input" title="用户输入会触发 DOM 事件。Angular 会通过事件绑定来监听那些事件，并把修改后的值传回应用的组件和模型中。" target="_self">用户输入</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/lifecycle-hooks" title="Angular 调用指令和组件的生命周期钩子函数，包括它的创建、变更和销毁时。" target="_self">生命周期钩子</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/component-interaction" title="在不同的指令和组件之间共享信息" target="_self">组件交互</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/component-styles" title="添加专属于某个组件的样式" target="_self">组件样式</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/elements" title="把组件转换成自定义元素。" target="_self">Angular 自定义元素</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dynamic-component-loader" title="动态加载组件" target="_self">动态组件</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 expanded selected ng-star-inserted" style="position:relative" href="guide/attribute-directives" title="属性型指令把行为添加到现有元素上。" target="_self">属性型指令</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/structural-directives" title="结构型指令可以操纵页面的布局" target="_self">结构型指令</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/pipes" title="管道可以在模板中转换显示的内容。" target="_self">管道</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular 的表单" aria-pressed="false">表单<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/forms-overview" title="表单可以创建集中、高效、引人注目的输入体验。Angular 表单可以协调一组数据绑定控件，跟踪变更，验证输入，并表达错误信息。" target="_self">简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/reactive-forms" title="使用 FormBuilder、表单组和表单数组创建响应式表单。" target="_self">响应式表单</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/forms" title="使用指令和 Angular 模板语法创建模板驱动表单。" target="_self">模板驱动表单</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/form-validation" title="验证用户的表单输入" target="_self">表单验证</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dynamic-form" title="使用 FormGroup 渲染动态表单。" target="_self">动态表单</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Observable 与 RxJS" aria-pressed="false">Observable 与 RxJS<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/observables" title="" target="_self">可观察对象(Observable)</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/rx-library" title="" target="_self">RxJS 库</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/observables-in-angular" title="" target="_self">Angular 中的可观察对象</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/practical-observable-usage" title="" target="_self">用法实战</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/comparing-observables" title="" target="_self">与其它技术的比较</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/bootstrapping" title="在应用的根模块（AppModule）中告诉 Angular 如何构造并引导引用。" target="_self">引导启动</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular 中的模块" aria-pressed="false">NgModule<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodules" title="使用 NgModule 让你的应用更高效" target="_self">NgModule 简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-vs-jsmodule" title="JavaScript 模块和 NgModule 之间的差异" target="_self">JS 模块 vs NgModule</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/frequent-ngmodules" title="介绍最常用的 NgModule" target="_self">常用模块</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/module-types" title="介绍特性模块的几种类型" target="_self">特性模块的分类</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/entry-components" title="关于 Angular 中入口组件的一切" target="_self">入口组件</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/feature-modules" title="创建特性模块，以组织你的代码" target="_self">特性模块</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/providers" title="服务提供商与 NgModule" target="_self">服务提供商</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/singleton-services" title="创建单例服务" target="_self">单例服务</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/lazy-loading-ngmodules" title="惰性加载模块，以提高应用的性能" target="_self">惰性加载的特性模块</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/sharing-ngmodules" title="共享 NgModule 让你的应用现代化。" target="_self">共享 NgModule</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-api" title="理解 NgModule 的那些细节。" target="_self">NgModule API</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ngmodule-faq" title="回答关于 NgModules 的常见问题。" target="_self">NgModule 常见问题</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="依赖注入：创建并注入各种服务。" aria-pressed="false">依赖注入<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection" title="Angular 的依赖注入系统能够为 Angular 创建的类创建并交付它们所依赖的服务。" target="_self">Angular 依赖注入</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/hierarchical-dependency-injection" title="与组件树平行的注入器树，并支持嵌套的依赖。" target="_self">多级注入器</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-providers" title="各种提供商类型的更多知识。" target="_self">DI 提供商</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-in-action" title="依赖注入的使用技巧" target="_self">DI 实战</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/dependency-injection-navtree" title="使用注入器树来查找父组件。" target="_self">浏览组件树</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/http" title="通过 HTTP 协议与远程服务器对话。" target="_self">HttpClient</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/router" title="揭示如何通过 Angular 路由进行基本的屏幕导航。" target="_self">路由与导航</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular 动画系统指南" aria-pressed="false">动画<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/animations" title="Angular 动画的基础技术。" target="_self">简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/transition-and-triggers" title="转场与触发器的高级技术。" target="_self">转场与触发器</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/complex-animation-sequences" title="复杂的 Angular 动画序列。" target="_self">复杂序列</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/reusable-animations" title="创建可复用的动画。" target="_self">可复用动画</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/route-animations" title="为路由提供转场动画。" target="_self">路由转场动画</a></div></aio-nav-item></div></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="把 Angular 用到你的实际工作中的一些技巧" aria-pressed="false">其它技术<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/security" title="Angular 应用开发中的安全技术。" target="_self">安全</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/i18n" title="把应用模板中的文本翻译成多种语言。" target="_self">国际化 (i18n)</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="Angular Service Worker: 控制应用资源的缓存。" aria-pressed="false">Service Worker 与 PWA<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-intro" title="Angular 对 Service Worker 的实现提升了慢速或不稳定的网络连接下的用户体验。" target="_self">简介</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-getting-started" title="在 CLI 项目中启用 Service Worker，并在浏览器中查看效果。" target="_self">快速起步</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-communications" title="那些能让你和 Angular 的 Service Worker 通讯的服务类。" target="_self">与 Service Worker 通讯</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-devops" title="使用 Service Worker 运行应用、管理应用更新、调试以及杀掉正在运行的应用。" target="_self">生产环境下的 Service Worker</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/service-worker-config" title="配置 Service Worker 的缓存行为。" target="_self">Service Worker 配置</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/universal" title="使用 Angular Universal 在服务端渲染 HTML。" target="_self">服务端渲染</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="把 AngularJS 应用增量式的升级到 Angular。" aria-pressed="false">从 AngularJS 升级<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/upgrade" title="把 AngularJS 应用增量式的升级到 Angular。" target="_self">升级步骤</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/upgrade-performance" title="用更灵活的方式把 AngularJS 升级到 Angular" target="_self">更关注性能的升级方式</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/ajs-quick-reference" title="学习如何把 AngularJS 的概念映射到 Angular 中。" target="_self">AngularJS 与 Angular 的概念对照</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="使用共享库扩展 Angular" aria-pressed="false">Angular 库开发<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/libraries" title="理解何时以及如何使用和创建库。" target="_self">库概览</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/using-libraries" title="把已发布的库集成进你的应用中。" target="_self">使用已发布的库</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/creating-libraries" title="通过创建、发布和使用你自己的库来扩展 Angular" target="_self">创建库</a></div></aio-nav-item></div></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="关于环境搭建、构建、测试、部署环境与工具的信息。" aria-pressed="false">环境搭建与部署<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/file-structure" title="Angular 工作区在文件系统中是怎样的。" target="_self">项目文件结构</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/workspace-config" title="&quot;angular.json&quot; 包含供 CLI 命令使用的工作区和项目默认配置。" target="_self">工作区配置</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/npm-packages" title="开发期间和运行期间所需的 npm 包的说明。" target="_self">npm 包</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/typescript-configuration" title="给 Angular 开发者的 TypeScript 配置。" target="_self">TypeScript 配置</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/aot-compiler" title="了解为何以及如何使用预先（AOT）编译器。" target="_self">预先（AOT）编译</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/build" title="构建应用及为应用启动开发服务器。" target="_self">构建与运行</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/testing" title="测试 Angular 应用的技巧与实践。" target="_self">测试</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/deployment" title="了解如何部署 Angular 应用。" target="_self">发布</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/browser-support" title="浏览器支持与腻子脚本指南。" target="_self">浏览器支持</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><button class="vertical-menu-item heading level-2 collapsed ng-star-inserted" type="button" title="整合开发环境和工具。" aria-pressed="false">开发工具集成<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-2 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-3 collapsed ng-star-inserted" style="position:relative" href="guide/language-service" title="使用 Angular 语言服务加速开发。" target="_self">语言服务</a></div></aio-nav-item></div></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="Angular 的版本发布实践、更新与升级。" aria-pressed="false">发布信息<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/updating" title="如何把 Angular 应用和库升级到最新版本。" target="_self">保持最新</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/releases" title="Angular 的版本、发布、支持、弃用策略与实践。" target="_self">Angular 发布策略与实践</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="Angular 语法、编码、术语汇总。" aria-pressed="false">快捷手册<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/cheatsheet" title="关于 Angular 常用编码技术的快速指南。" target="_self">速查表</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/styleguide" title="写出 Angular 风格的程序" target="_self">风格指南</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="guide/glossary" title="Angular 中最重要的词汇的简要定义。" target="_self">词汇表</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><button class="vertical-menu-item heading level-1 collapsed ng-star-inserted" type="button" title="Angular CLI 命令参考手册。" aria-pressed="false">CLI 命令<mat-icon class="rotating-icon mat-icon" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><div class="heading-children level-1 collapsed"><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli" title="CLI 工具介绍、命令、语法" target="_self">概览</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/add" title="ng add." target="_self">ng add</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/build" title="ng build." target="_self">ng build</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/config" title="ng config." target="_self">ng config</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/doc" title="ng doc." target="_self">ng doc</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/e2e" title="ng e2e." target="_self">ng e2e</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/generate" title="ng generate." target="_self">ng generate</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/help" title="ng help." target="_self">ng help</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/lint" title="ng lint." target="_self">ng lint</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/new" title="ng new." target="_self">ng new</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/run" title="ng run." target="_self">ng run</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/serve" title="ng serve." target="_self">ng serve</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/test" title="ng test." target="_self">ng test</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/update" title="ng update." target="_self">ng update</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/version" title="ng version." target="_self">ng version</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted"><div class="ng-star-inserted"><a class="vertical-menu-item level-2 collapsed ng-star-inserted" style="position:relative" href="cli/xi18n" title="ng xi18n." target="_self">ng xi18n</a></div></aio-nav-item></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="api" title="关于 Angular 中类和值的详细信息。" target="_self">API 参考手册</a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><div class="mat-divider ng-star-inserted" style="margin:4px 20px;border-top:1px solid #d3d3d3"></div></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://ng-china.org" title="2018 ngChina 开发者大会" target="_blank">2018 ngChina @ 杭州<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://github.com/ng-docs/ng-docs.github.io/issues" title="github 上的中文互助问答区" target="_blank">互助问答<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://material.angular.cn" title="Angular Material 组件库的中文文档" target="_blank">官方 Material 组件库<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://ng.ant.design/" title="Ant Design 的 Angular 实现，服务于企业级后台产品。" target="_blank">ng-zorro 组件库<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item><aio-nav-item class="ng-star-inserted" style=""><div class="ng-star-inserted"><a class="vertical-menu-item level-1 collapsed ng-star-inserted" style="position:relative" href="https://ng.mobile.ant.design/" title="Ant Design Mobile 的 Angular 实现，服务于无线产品。" target="_blank">ng-zorro mobile 组件库<mat-icon class="mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">open_in_new</mat-icon></a></div></aio-nav-item></aio-nav-menu><div class="doc-version"><aio-select><div class="form-select-menu"><button class="form-select-button"><strong></strong>stable (v8.0.0-beta.4)</button></div></aio-select></div></div></mat-sidenav><div class="cdk-visually-hidden cdk-focus-trap-anchor"></div><mat-sidenav-content cdkscrollable="" class="mat-drawer-content mat-sidenav-content ng-star-inserted" style="margin-left:260px"><main class="sidenav-content" role="main" id="guide-attribute-directives"><aio-mode-banner></aio-mode-banner><aio-doc-viewer class=""><div style="opacity:1"><div class="github-links"><a href="https://github.com/angular/angular-cn/edit/aio/aio/content/guide/attribute-directives.md?message=docs%3A%20请简述你的修改..." aria-label="提供编辑建议" title="提供编辑建议"><i class="material-icons" aria-hidden="true" role="img">mode_edit</i></a></div><div class="content"><h1 id="attribute-directives" translation-result="on">属性型指令<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#attribute-directives"><i class="material-icons">link</i></a></h1><aio-toc class="embedded" ng-version="7.0.0"><div class="toc-inner no-print collapsed ng-star-inserted"><button aria-label="Expand/collapse contents" class="toc-heading embedded secondary ng-star-inserted" title="Expand/collapse contents" type="button" aria-pressed="false">目录<mat-icon class="rotating-icon mat-icon collapsed" role="img" svgicon="keyboard_arrow_right" aria-hidden="true"><svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"></path></svg></mat-icon></button><ul class="toc-list embedded"><li title="指令概览link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#directives-overview">指令概览</a></li><li title="创建一个简单的属性型指令link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#build-a-simple-attribute-directive">创建一个简单的属性型指令</a></li><li title="编写指令代码link" class="h3 ng-star-inserted"><a href="guide/attribute-directives#write-the-directive-code">编写指令代码</a></li><li title="使用属性型指令link" class="h2 secondary ng-star-inserted"><a href="guide/attribute-directives#apply-the-attribute-directive">使用属性型指令</a></li><li title="响应用户引发的事件link" class="h2 secondary ng-star-inserted"><a href="guide/attribute-directives#respond-to-user-initiated-events">响应用户引发的事件</a></li><li title="使用 @Input 数据绑定向指令传递值link" class="h2 secondary ng-star-inserted"><a href="guide/attribute-directives#pass-values-into-the-directive-with-an-input-data-binding">使用 <code>@Input</code> 数据绑定向指令传递值</a></li><li title="绑定到 @Input 属性link" class="h3 secondary ng-star-inserted"><a href="guide/attribute-directives#binding-to-an-input-property">绑定到 <em>@Input</em> 属性</a></li><li title="绑定到 @Input 别名link" class="h3 secondary ng-star-inserted"><a href="guide/attribute-directives#bind-to-an-input-alias">绑定到 <em>@Input</em> 别名</a></li><li title="写个测试程序试验下link" class="h2 secondary ng-star-inserted"><a href="guide/attribute-directives#write-a-harness-to-try-it">写个测试程序试验下</a></li><li title="绑定到第二个属性link" class="h2 secondary ng-star-inserted"><a href="guide/attribute-directives#bind-to-a-second-property">绑定到第二个属性</a></li><li title="小结link" class="h2 secondary ng-star-inserted"><a href="guide/attribute-directives#summary">小结</a></li><li title="附录：为什么要加@Input？link" class="h3 secondary ng-star-inserted"><a href="guide/attribute-directives#appendix-why-add-input">附录：为什么要加<em>@Input</em>？</a></li></ul><button aria-label="Expand/collapse contents" class="toc-more-items embedded material-icons collapsed ng-star-inserted" title="Expand/collapse contents" type="button" aria-pressed="false"></button></div></aio-toc><h1 translation-origin="off" id="attribute-directives">Attribute Directives<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#attribute-directives"><i class="material-icons">link</i></a></h1><p translation-result="on"><strong>属性</strong>型指令用于改变一个 DOM 元素的外观或行为。</p><p translation-origin="off">An <strong>Attribute</strong> directive changes the appearance or behavior of a DOM element.</p><p translation-result="on">你可以到这里试试：<live-example title="属性型指令范例" ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/attribute-directives/stackblitz.html" title="属性型指令范例">属性型指令范例</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/attribute-directives/attribute-directives.zip">下载范例</a></span></span></span></live-example>。</p><p translation-origin="off">Try the<live-example title="Attribute Directive example" ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/attribute-directives/stackblitz.html" title="Attribute Directive example">Attribute Directive example</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/attribute-directives/attribute-directives.zip">下载范例</a></span></span></span></live-example>.</p><a id="directive-overview"></a><h2 id="directives-overview" translation-result="on">指令概览<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#directives-overview"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="directives-overview">Directives overview<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#directives-overview"><i class="material-icons">link</i></a></h2><p translation-result="on">在 Angular 中有三种类型的指令：</p><p translation-origin="off">There are three kinds of directives in Angular:</p><ol><li><p translation-result="on">组件 — 拥有模板的指令</p><p translation-origin="off">Components—directives with a template.</p></li><li><p translation-result="on">结构型指令 — 通过添加和移除 DOM 元素改变 DOM 布局的指令</p><p translation-origin="off">Structural directives—change the DOM layout by adding and removing DOM elements.</p></li><li><p translation-result="on">属性型指令 — 改变元素、组件或其它指令的外观和行为的指令。</p><p translation-origin="off">Attribute directives—change the appearance or behavior of an element, component, or another directive.</p></li></ol><p translation-result="on"><em>组件</em>是这三种指令中最常用的。 你在<a href="guide/quickstart">快速上手</a>例子中第一次见到组件。</p><p translation-origin="off"><em>Components</em> are the most common of the three directives. You saw a component for the first time in the <a href="guide/quickstart">Getting Started</a>.</p><p translation-result="on"><em>结构型</em>指令修改视图的结构。例如，<a href="guide/template-syntax#ngFor">NgFor</a> 和 <a href="guide/template-syntax#ngIf">NgIf</a>。 要了解更多，参见<a href="guide/structural-directives">结构型指令</a> guide。</p><p translation-origin="off"><em>Structural Directives</em> change the structure of the view. Two examples are <a href="guide/template-syntax#ngFor">NgFor</a> and <a href="guide/template-syntax#ngIf">NgIf</a>. Learn about them in the <a href="guide/structural-directives">Structural Directives</a> guide.</p><p translation-result="on"><em>属性型</em>指令改变一个元素的外观或行为。例如，内置的 <a href="guide/template-syntax#ngStyle">NgStyle</a> 指令可以同时修改元素的多个样式。</p><p translation-origin="off"><em>Attribute directives</em> are used as attributes of elements. The built-in <a href="guide/template-syntax#ngStyle">NgStyle</a> directive in the <a href="guide/template-syntax">Template Syntax</a> guide, for example, can change several element styles at the same time.</p><h2 id="build-a-simple-attribute-directive" translation-result="on">创建一个简单的属性型指令<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#build-a-simple-attribute-directive"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="build-a-simple-attribute-directive">Build a simple attribute directive<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#build-a-simple-attribute-directive"><i class="material-icons">link</i></a></h2><p translation-result="on">属性型指令至少需要一个带有 <code>@<a href="api/core/Directive" class="code-anchor">Directive</a></code> 装饰器的控制器类。该装饰器指定了一个用于标识属性的选择器。 控制器类实现了指令需要的指令行为。</p><p translation-origin="off">An attribute directive minimally requires building a controller class annotated with <code>@<a href="api/core/Directive" class="code-anchor">Directive</a></code>, which specifies the selector that identifies the attribute. The controller class implements the desired directive behavior.</p><p translation-result="on">本章展示了如何创建一个简单的属性型指令 <em>myHighlight</em> ，当用户把鼠标悬停在一个元素上时，改变它的背景色。你可以这样用它：</p><p translation-origin="off">This page demonstrates building a simple <em>appHighlight</em> attribute directive to set an element's background color when the user hovers over that element. You can apply it like this:</p><code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html (applied)" region="applied" ng-version="7.0.0"><div style="display:none">&lt;p appHighlight&gt;Highlight me!&lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html (applied)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html (applied)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p</span><span class="pln"> </span><span class="atn">appHighlight</span><span class="tag">&gt;</span><span class="pln">Highlight me!</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><a id="write-directive"></a><h3 id="write-the-directive-code" translation-result="on">编写指令代码<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#write-the-directive-code"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="write-the-directive-code">Write the directive code<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#write-the-directive-code"><i class="material-icons">link</i></a></h3><p translation-result="on">在命令行窗口下用 CLI 命令 <a href="cli/generate"><code>ng generate directive</code></a>创建指令类文件。</p><p translation-origin="off">Create the directive class file in a terminal window with the CLI command <a href="cli/generate"><code>ng generate directive</code></a>.</p><code-example language="sh" class="code-shell" ng-version="7.0.0"><div style="display:none">ng generate directive highlight</div><aio-code><pre class="prettyprint lang-sh">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="pln">ng generate directive highlight</span></code>
    </pre></aio-code></code-example><p translation-result="on">CLI 会创建 <code>src/app/highlight.directive.ts</code> 及相应的测试文件（<code>.../spec.ts</code>），并且在根模块 <code>AppModule</code> 中声明这个指令类。</p><p translation-origin="off">The CLI creates <code>src/app/highlight.directive.ts</code>, a corresponding test file (<code>.../spec.ts</code>, and <em>declares</em> the directive class in the root <code>AppModule</code>.</p><div class="alert is-helpful"><p translation-result="on">和<strong>组件</strong>一样，这些<strong>指令</strong>也必须在<a href="guide/ngmodules">Angular 模块</a>中进行声明。</p><p translation-origin="off"><em>Directives</em> must be declared in <a href="guide/ngmodules">Angular Modules</a> in the same manner as <em>components</em>.</p></div><p translation-result="on">生成的 <code>src/app/highlight.directive.ts</code> 文件如下：</p><p translation-origin="off">The generated <code>src/app/highlight.directive.ts</code> is as follows:</p><code-example path="attribute-directives/src/app/highlight.directive.0.ts" header="src/app/highlight.directive.ts" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Directive" class="code-anchor">Directive</a> } from '@angular/core'; @<a href="api/core/Directive" class="code-anchor">Directive</a>({ selector: '[appHighlight]' }) export class HighlightDirective { constructor() { } }</div><header class="ng-star-inserted">src/app/highlight.directive.ts</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Directive" class="code-anchor"><span class="typ">Directive</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Directive" class="code-anchor"><span class="lit">Directive</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'[appHighlight]'</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HighlightDirective</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">constructor</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">这里导入的 <code><a href="api/core/Directive" class="code-anchor">Directive</a></code> 符号提供了 Angular 的 <code>@<a href="api/core/Directive" class="code-anchor">Directive</a></code> 装饰器。</p><p translation-origin="off">The imported <code><a href="api/core/Directive" class="code-anchor">Directive</a></code> symbol provides Angular the <code>@<a href="api/core/Directive" class="code-anchor">Directive</a></code> decorator.</p><p translation-result="on"><code>@<a href="api/core/Directive" class="code-anchor">Directive</a></code> 装饰器的配置属性中指定了该指令的 <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors">CSS 属性型选择器</a> <code>[appHighlight]</code></p><p translation-origin="off">The <code>@<a href="api/core/Directive" class="code-anchor">Directive</a></code> decorator's lone configuration property specifies the directive's <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors">CSS attribute selector</a>, <code>[appHighlight]</code>.</p><p translation-result="on">这里的方括号(<code>[]</code>)表示它的属性型选择器。 Angular 会在模板中定位每个拥有名叫 <code>appHighlight</code> 属性的元素，并且为这些元素加上本指令的逻辑。</p><p translation-origin="off">It's the brackets (<code>[]</code>) that make it an attribute selector. Angular locates each element in the template that has an attribute named <code>appHighlight</code> and applies the logic of this directive to that element.</p><p translation-result="on">正因如此，这类指令被称为 <strong>属性选择器</strong> 。</p><p translation-origin="off">The <em>attribute selector</em> pattern explains the name of this kind of directive.</p><div class="alert is-helpful"><h4 id="why-not-highlight" translation-result="on">为什么不直接叫做 "highlight"？<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#why-not-highlight"><i class="material-icons">link</i></a></h4><h4 translation-origin="off" id="why-not-highlight">Why not "highlight"?<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#why-not-highlight"><i class="material-icons">link</i></a></h4><p translation-result="on">尽管 <em>highlight</em> 是一个比 <em>myHighlight</em> 更简洁的名字，而且它确实也能工作。 但是最佳实践是在选择器名字前面添加前缀，以确保它们不会与标准 HTML 属性冲突。 它同时减少了与第三方指令名字发生冲突的危险。</p><p translation-origin="off">Though <em>highlight</em> would be a more concise selector than <em>appHighlight</em> and it would work, the best practice is to prefix selector names to ensure they don't conflict with standard HTML attributes. This also reduces the risk of colliding with third-party directive names. The CLI added the <code>app</code> prefix for you.</p><p translation-result="on">确认你<strong>没有</strong>给 <code>highlight</code> 指令添加<strong><code>ng</code></strong>前缀。 那个前缀属于 Angular，使用它可能导致难以诊断的 bug。例如，这个简短的前缀 <code>my</code> 可以帮助你区分自定义指令。</p><p translation-origin="off">Make sure you do <strong>not</strong> prefix the <code>highlight</code> directive name with <strong><code>ng</code></strong>because that prefix is reserved for Angular and using it could cause bugs that are difficult to diagnose.</p></div><p translation-result="on">紧跟在 <code>@<a href="api/core/Directive" class="code-anchor">Directive</a></code> 元数据之后的就是该指令的控制器类，名叫 <code>HighlightDirective</code>，它包含了该指令的逻辑（目前为空逻辑）。然后导出 <code>HighlightDirective</code>，以便它能在别处访问到。</p><p translation-origin="off">After the <code>@<a href="api/core/Directive" class="code-anchor">Directive</a></code> metadata comes the directive's controller class, called <code>HighlightDirective</code>, which contains the (currently empty) logic for the directive. Exporting <code>HighlightDirective</code> makes the directive accessible.</p><p translation-result="on">现在，把刚才生成的 <code>src/app/highlight.directive.ts</code> 编辑成这样：</p><p translation-origin="off">Now edit the generated <code>src/app/highlight.directive.ts</code> to look as follows:</p><code-example path="attribute-directives/src/app/highlight.directive.1.ts" header="src/app/highlight.directive.ts" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Directive" class="code-anchor">Directive</a>, <a href="api/core/ElementRef" class="code-anchor">ElementRef</a> } from '@angular/core'; @<a href="api/core/Directive" class="code-anchor">Directive</a>({ selector: '[appHighlight]' }) export class HighlightDirective { constructor(el: <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>) { el.nativeElement.style.backgroundColor = 'yellow'; } }</div><header class="ng-star-inserted">src/app/highlight.directive.ts</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Directive" class="code-anchor"><span class="typ">Directive</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Directive" class="code-anchor"><span class="lit">Directive</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'[appHighlight]'</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HighlightDirective</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">constructor</span><span class="pun">(</span><span class="pln">el</span><span class="pun">:</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
       el</span><span class="pun">.</span><span class="pln">nativeElement</span><span class="pun">.</span><span class="pln">style</span><span class="pun">.</span><span class="pln">backgroundColor </span><span class="pun">=</span><span class="pln"> </span><span class="str">'yellow'</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>import</code> 语句还从 Angular 的 <code>core</code> 库中导入了一个 <code><a href="api/core/ElementRef" class="code-anchor">ElementRef</a></code> 符号。</p><p translation-origin="off">The <code>import</code> statement specifies an additional <code><a href="api/core/ElementRef" class="code-anchor">ElementRef</a></code> symbol from the Angular <code>core</code> library:</p><p translation-result="on">你可以在指令的构造函数中使用 <code><a href="api/core/ElementRef" class="code-anchor">ElementRef</a></code> 来<a href="guide/dependency-injection">注入</a>宿主 DOM 元素的引用，也就是你放置 <code>appHighlight</code> 的那个元素。</p><p translation-origin="off">You use the <code><a href="api/core/ElementRef" class="code-anchor">ElementRef</a></code> in the directive's constructor to <a href="guide/dependency-injection">inject</a> a reference to the host DOM element, the element to which you applied <code>appHighlight</code>.</p><p translation-result="on"><code><a href="api/core/ElementRef" class="code-anchor">ElementRef</a></code> 通过其 <code>nativeElement</code> 属性给你了直接访问宿主 DOM 元素的能力。</p><p translation-origin="off"><code><a href="api/core/ElementRef" class="code-anchor">ElementRef</a></code> grants direct access to the host DOM element through its <code>nativeElement</code> property.</p><p translation-result="on">这里的第一个实现把宿主元素的背景色设置为了黄色。</p><p translation-origin="off">This first implementation sets the background color of the host element to yellow.</p><a id="apply-directive"></a><h2 id="apply-the-attribute-directive" translation-result="on">使用属性型指令<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#apply-the-attribute-directive"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="apply-the-attribute-directive">Apply the attribute directive<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#apply-the-attribute-directive"><i class="material-icons">link</i></a></h2><p translation-result="on">要想使用这个新的 <code>HighlightDirective</code>，就往根组件 <code>AppComponent</code> 的模板中添加一个 <code>&lt;p&gt;</code> 元素，并把该指令作为一个属性使用。</p><p translation-origin="off">To use the new <code>HighlightDirective</code>, add a paragraph (<code>&lt;p&gt;</code>) element to the template of the root <code>AppComponent</code> and apply the directive as an attribute.</p><code-example path="attribute-directives/src/app/app.component.1.html" header="src/app/app.component.html" region="applied" ng-version="7.0.0"><div style="display:none">&lt;p appHighlight&gt;Highlight me!&lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p</span><span class="pln"> </span><span class="atn">appHighlight</span><span class="tag">&gt;</span><span class="pln">Highlight me!</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">运行这个应用以查看 <code>HighlightDirective</code> 的实际效果。</p><p translation-origin="off">Now run the application to see the <code>HighlightDirective</code> in action.</p><code-example language="sh" class="code-shell" ng-version="7.0.0"><div style="display:none">ng serve</div><aio-code><pre class="prettyprint lang-sh">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="pln">ng serve</span></code>
    </pre></aio-code></code-example><p translation-result="on">总结：Angular 在<strong>宿主</strong>元素 <code>&lt;p&gt;</code> 上发现了一个 <code>appHighlight</code> 属性。 然后它创建了一个 <code>HighlightDirective</code> 类的实例，并把所在元素的引用注入到了指令的构造函数中。 在构造函数中，该指令把 <code>&lt;p&gt;</code> 元素的背景设置为了黄色。</p><p translation-origin="off">To summarize, Angular found the <code>appHighlight</code> attribute on the <strong>host</strong> <code>&lt;p&gt;</code> element. It created an instance of the <code>HighlightDirective</code> class and injected a reference to the <code>&lt;p&gt;</code> element into the directive's constructor which sets the <code>&lt;p&gt;</code> element's background style to yellow.</p><a id="respond-to-user"></a><h2 id="respond-to-user-initiated-events" translation-result="on">响应用户引发的事件<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#respond-to-user-initiated-events"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="respond-to-user-initiated-events">Respond to user-initiated events<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#respond-to-user-initiated-events"><i class="material-icons">link</i></a></h2><p translation-result="on">当前，<code>appHighlight</code> 只是简单的设置元素的颜色。 这个指令应该在用户鼠标悬浮一个元素时，设置它的颜色。</p><p translation-origin="off">Currently, <code>appHighlight</code> simply sets an element color. The directive could be more dynamic. It could detect when the user mouses into or out of the element and respond by setting or clearing the highlight color.</p><p translation-result="on">先把 <code><a href="api/core/HostListener" class="code-anchor">HostListener</a></code> 加进导入列表中。</p><p translation-origin="off">Begin by adding <code><a href="api/core/HostListener" class="code-anchor">HostListener</a></code> to the list of imported symbols.</p><code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (imports)" region="imports" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Directive" class="code-anchor">Directive</a>, <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>, <a href="api/core/HostListener" class="code-anchor">HostListener</a> } from '@angular/core';</div><header class="ng-star-inserted">src/app/highlight.directive.ts (imports)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (imports)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Directive" class="code-anchor"><span class="typ">Directive</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/HostListener" class="code-anchor"><span class="typ">HostListener</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span></code>
    </pre></aio-code></code-example><p translation-result="on">然后使用 <code><a href="api/core/HostListener" class="code-anchor">HostListener</a></code> 装饰器添加两个事件处理器，它们会在鼠标进入或离开时进行响应。</p><p translation-origin="off">Then add two eventhandlers that respond when the mouse enters or leaves, each adorned by the <code><a href="api/core/HostListener" class="code-anchor">HostListener</a></code> decorator.</p><code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (mouse-methods)" region="mouse-methods" ng-version="7.0.0"><div style="display:none">@<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseenter') onMouseEnter() { this.highlight('yellow'); } @<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseleave') onMouseLeave() { this.highlight(null); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; }</div><header class="ng-star-inserted">src/app/highlight.directive.ts (mouse-methods)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (mouse-methods)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/HostListener" class="code-anchor"><span class="lit">HostListener</span></a><span class="pun">(</span><span class="str">'mouseenter'</span><span class="pun">)</span><span class="pln"> onMouseEnter</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlight</span><span class="pun">(</span><span class="str">'yellow'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/HostListener" class="code-anchor"><span class="lit">HostListener</span></a><span class="pun">(</span><span class="str">'mouseleave'</span><span class="pun">)</span><span class="pln"> onMouseLeave</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlight</span><span class="pun">(</span><span class="kwd">null</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">

</span><span class="kwd">private</span><span class="pln"> highlight</span><span class="pun">(</span><span class="pln">color</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">el</span><span class="pun">.</span><span class="pln">nativeElement</span><span class="pun">.</span><span class="pln">style</span><span class="pun">.</span><span class="pln">backgroundColor </span><span class="pun">=</span><span class="pln"> color</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>@<a href="api/core/HostListener" class="code-anchor">HostListener</a></code> 装饰器让你订阅某个属性型指令所在的宿主 DOM 元素的事件，在这个例子中就是 <code>&lt;p&gt;</code>。</p><p translation-origin="off">The <code>@<a href="api/core/HostListener" class="code-anchor">HostListener</a></code> decorator lets you subscribe to events of the DOM element that hosts an attribute directive, the <code>&lt;p&gt;</code> in this case.</p><div class="alert is-helpful"><p translation-result="on">当然，你可以通过标准的 JavaScript 方式手动给宿主 DOM 元素附加一个事件监听器。 但这种方法至少有三个问题：</p><p translation-origin="off">Of course you could reach into the DOM with standard JavaScript and attach event listeners manually. There are at least three problems with <em>that</em> approach:</p><ol><li><p translation-result="on">必须正确的书写事件监听器。</p><p translation-origin="off">You have to write the listeners correctly.</p></li><li><p translation-result="on">当指令被销毁的时候，必须<em>拆卸</em>事件监听器，否则会导致内存泄露。</p><p translation-origin="off">The code must <em>detach</em> the listener when the directive is destroyed to avoid memory leaks.</p></li><li><p translation-result="on">必须直接和 DOM API 打交道，应该避免这样做。</p><p translation-origin="off">Talking to DOM API directly isn't a best practice.</p></li></ol></div><p translation-result="on">这些处理器委托了一个辅助方法来为 DOM 元素（<code>el</code>）设置颜色。</p><p translation-origin="off">The handlers delegate to a helper method that sets the color on the host DOM element, <code>el</code>.</p><p translation-result="on">这个辅助方法（<code>highlight</code>）被从构造函数中提取了出来。 修改后的构造函数只负责声明要注入的元素 <code>el: <a href="api/core/ElementRef" class="code-anchor">ElementRef</a></code>。</p><p translation-origin="off">The helper method, <code>highlight</code>, was extracted from the constructor. The revised constructor simply declares the injected <code>el: <a href="api/core/ElementRef" class="code-anchor">ElementRef</a></code>.</p><code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (constructor)" region="ctor" ng-version="7.0.0"><div style="display:none">constructor(private el: <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>) { }</div><header class="ng-star-inserted">src/app/highlight.directive.ts (constructor)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (constructor)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">private</span><span class="pln"> el</span><span class="pun">:</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">下面是修改后的指令代码：</p><p translation-origin="off">Here's the updated directive in full:</p><code-example path="attribute-directives/src/app/highlight.directive.2.ts" header="src/app/highlight.directive.ts" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Directive" class="code-anchor">Directive</a>, <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>, <a href="api/core/HostListener" class="code-anchor">HostListener</a> } from '@angular/core'; @<a href="api/core/Directive" class="code-anchor">Directive</a>({ selector: '[appHighlight]' }) export class HighlightDirective { constructor(private el: <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>) { } @<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseenter') onMouseEnter() { this.highlight('yellow'); } @<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseleave') onMouseLeave() { this.highlight(null); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; } }</div><header class="ng-star-inserted">src/app/highlight.directive.ts</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><ol class="linenums"><li class="L0"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Directive" class="code-anchor"><span class="typ">Directive</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/HostListener" class="code-anchor"><span class="typ">HostListener</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span></li><li class="L1"><span class="pln">&nbsp;</span></li><li class="L2"><span class="lit">@</span><a href="api/core/Directive" class="code-anchor"><span class="lit">Directive</span></a><span class="pun">({</span></li><li class="L3"><span class="pln">  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'[appHighlight]'</span></li><li class="L4"><span class="pun">})</span></li><li class="L5"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HighlightDirective</span><span class="pln"> </span><span class="pun">{</span></li><li class="L6"><span class="pln">  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">private</span><span class="pln"> el</span><span class="pun">:</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span></li><li class="L7"><span class="pln">&nbsp;</span></li><li class="L8"><span class="pln">  </span><span class="lit">@</span><a href="api/core/HostListener" class="code-anchor"><span class="lit">HostListener</span></a><span class="pun">(</span><span class="str">'mouseenter'</span><span class="pun">)</span><span class="pln"> onMouseEnter</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></li><li class="L9"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlight</span><span class="pun">(</span><span class="str">'yellow'</span><span class="pun">);</span></li><li class="L0"><span class="pln">  </span><span class="pun">}</span></li><li class="L1"><span class="pln">&nbsp;</span></li><li class="L2"><span class="pln">  </span><span class="lit">@</span><a href="api/core/HostListener" class="code-anchor"><span class="lit">HostListener</span></a><span class="pun">(</span><span class="str">'mouseleave'</span><span class="pun">)</span><span class="pln"> onMouseLeave</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span></li><li class="L3"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlight</span><span class="pun">(</span><span class="kwd">null</span><span class="pun">);</span></li><li class="L4"><span class="pln">  </span><span class="pun">}</span></li><li class="L5"><span class="pln">&nbsp;</span></li><li class="L6"><span class="pln">  </span><span class="kwd">private</span><span class="pln"> highlight</span><span class="pun">(</span><span class="pln">color</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span></li><li class="L7"><span class="pln">    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">el</span><span class="pun">.</span><span class="pln">nativeElement</span><span class="pun">.</span><span class="pln">style</span><span class="pun">.</span><span class="pln">backgroundColor </span><span class="pun">=</span><span class="pln"> color</span><span class="pun">;</span></li><li class="L8"><span class="pln">  </span><span class="pun">}</span></li><li class="L9"><span class="pun">}</span></li></ol></code>
    </pre></aio-code></code-example><p translation-result="on">运行本应用并确认：当把鼠标移到 <code>p</code> 上的时候，背景色就出现了，而移开时就消失了。</p><p translation-origin="off">Run the app and confirm that the background color appears when the mouse hovers over the <code>p</code> and disappears as it moves out.</p><figure><img src="generated/images/guide/attribute-directives/highlight-directive-anim.gif" alt="Second Highlight" width="204" height="72"></figure><a id="bindings"></a><h2 id="pass-values-into-the-directive-with-an-input-data-binding" translation-result="on">使用 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 数据绑定向指令传递值<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#pass-values-into-the-directive-with-an-input-data-binding"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="pass-values-into-the-directive-with-an-input-data-binding">Pass values into the directive with an <em>@Input</em> data binding<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#pass-values-into-the-directive-with-an-input-data-binding"><i class="material-icons">link</i></a></h2><p translation-result="on">高亮的颜色目前是硬编码在指令中的，这不够灵活。 在这一节中，你应该让指令的使用者可以指定要用哪种颜色进行高亮。</p><p translation-origin="off">Currently the highlight color is hard-coded <em>within</em> the directive. That's inflexible. In this section, you give the developer the power to set the highlight color while applying the directive.</p><p translation-result="on">先从 <code>@angular/core</code> 中导入 <code><a href="api/core/Input" class="code-anchor">Input</a></code>。</p><p translation-origin="off">Begin by adding <code><a href="api/core/Input" class="code-anchor">Input</a></code> to the list of symbols imported from <code>@angular/core</code>.</p><code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" header="src/app/highlight.directive.ts (imports)" region="imports" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Directive" class="code-anchor">Directive</a>, <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>, <a href="api/core/HostListener" class="code-anchor">HostListener</a>, <a href="api/core/Input" class="code-anchor">Input</a> } from '@angular/core';</div><header class="ng-star-inserted">src/app/highlight.directive.ts (imports)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (imports)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Directive" class="code-anchor"><span class="typ">Directive</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/HostListener" class="code-anchor"><span class="typ">HostListener</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/Input" class="code-anchor"><span class="typ">Input</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span></code>
    </pre></aio-code></code-example><p translation-result="on">然后把 <code>highlightColor</code> 属性添加到指令类中，就像这样：</p><p translation-origin="off">Add a <code>highlightColor</code> property to the directive class like this:</p><code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (highlightColor)" region="color" ng-version="7.0.0"><div style="display:none">@<a href="api/core/Input" class="code-anchor">Input</a>() highlightColor: string;</div><header class="ng-star-inserted">src/app/highlight.directive.ts (highlightColor)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (highlightColor)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">()</span><span class="pln"> highlightColor</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span></code>
    </pre></aio-code></code-example><a id="input"></a><h3 id="binding-to-an-input-property" translation-result="on">绑定到 <em>@Input</em> 属性<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#binding-to-an-input-property"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="binding-to-an-input-property">Binding to an <em>@Input</em> property<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#binding-to-an-input-property"><i class="material-icons">link</i></a></h3><p translation-result="on">注意看 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 装饰器。它往类上添加了一些元数据，从而让该指令的 <code>highlightColor</code> 能用于绑定。</p><p translation-origin="off">Notice the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator. It adds metadata to the class that makes the directive's <code>highlightColor</code> property available for binding.</p><p translation-result="on">它之所以称为<em>输入</em>属性，是因为数据流是从绑定表达式流向指令内部的。 如果没有这个元数据，Angular 就会拒绝绑定，参见<a href="guide/attribute-directives#why-input" title="为什么要添加@Input?">稍后</a>了解更多。</p><p translation-origin="off">It's called an <em>input</em> property because data flows from the binding expression <em>into</em> the directive. Without that input metadata, Angular rejects the binding; see <a href="guide/attribute-directives#why-input" title="Why add @Input?">below</a> for more about that.</p><p translation-result="on">试试把下列指令绑定变量添加到 <code>AppComponent</code> 的模板中：</p><p translation-origin="off">Try it by adding the following directive binding variations to the <code>AppComponent</code> template:</p><code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html (excerpt)" region="color-1" ng-version="7.0.0"><div style="display:none">&lt;p appHighlight highlightColor="yellow"&gt;Highlighted in yellow&lt;/p&gt; &lt;p appHighlight [highlightColor]="'orange'"&gt;Highlighted in orange&lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html (excerpt)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html (excerpt)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p</span><span class="pln"> </span><span class="atn">appHighlight</span><span class="pln"> </span><span class="atn">highlightColor</span><span class="pun">=</span><span class="atv">"yellow"</span><span class="tag">&gt;</span><span class="pln">Highlighted in yellow</span><span class="tag">&lt;/p&gt;</span><span class="pln">
</span><span class="tag">&lt;p</span><span class="pln"> </span><span class="atn">appHighlight</span><span class="pln"> [</span><span class="atn">highlightColor</span><span class="pln">]</span><span class="pun">=</span><span class="atv">"'orange'"</span><span class="tag">&gt;</span><span class="pln">Highlighted in orange</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">把 <code>color</code> 属性添加到 <code>AppComponent</code> 中：</p><p translation-origin="off">Add a <code>color</code> property to the <code>AppComponent</code>.</p><code-example path="attribute-directives/src/app/app.component.1.ts" linenums="false" header="src/app/app.component.ts (class)" region="class" ng-version="7.0.0"><div style="display:none">export class AppComponent { color = 'yellow'; }</div><header class="ng-star-inserted">src/app/app.component.ts (class)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.ts (class)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AppComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  color </span><span class="pun">=</span><span class="pln"> </span><span class="str">'yellow'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">让它通过属性绑定来控制高亮颜色。</p><p translation-origin="off">Let it control the highlight color with a property binding.</p><code-example path="attribute-directives/src/app/app.component.1.html" linenums="false" header="src/app/app.component.html (excerpt)" region="color-2" ng-version="7.0.0"><div style="display:none">&lt;p appHighlight [highlightColor]="color"&gt;Highlighted with parent component's color&lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html (excerpt)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html (excerpt)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p</span><span class="pln"> </span><span class="atn">appHighlight</span><span class="pln"> [</span><span class="atn">highlightColor</span><span class="pln">]</span><span class="pun">=</span><span class="atv">"color"</span><span class="tag">&gt;</span><span class="pln">Highlighted with parent component's color</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">很不错，但如果可以在应用该指令时在<em>同一个属性</em>中设置颜色就更好了，就像这样：</p><p translation-origin="off">That's good, but it would be nice to <em>simultaneously</em> apply the directive and set the color <em>in the same attribute</em> like this.</p><code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (color)" region="color" ng-version="7.0.0"><div style="display:none">&lt;p [appHighlight]="color"&gt;Highlight me!&lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html (color)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html (color)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p</span><span class="pln"> [</span><span class="atn">appHighlight</span><span class="pln">]</span><span class="pun">=</span><span class="atv">"color"</span><span class="tag">&gt;</span><span class="pln">Highlight me!</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on"><code>[appHighlight]</code> 属性同时做了两件事：把这个高亮指令应用到了 <code>&lt;p&gt;</code> 元素上，并且通过属性绑定设置了该指令的高亮颜色。 你复用了该指令的属性选择器 <code>[appHighlight]</code> 来同时完成它们。 这是清爽、简约的语法。</p><p translation-origin="off">The <code>[appHighlight]</code> attribute binding both applies the highlighting directive to the <code>&lt;p&gt;</code> element and sets the directive's highlight color with a property binding. You're re-using the directive's attribute selector (<code>[appHighlight]</code>) to do both jobs. That's a crisp, compact syntax.</p><p translation-result="on">你还要把该指令的 <code>highlightColor</code> 改名为 <code>appHighlight</code>，因为它是颜色属性目前的绑定名。</p><p translation-origin="off">You'll have to rename the directive's <code>highlightColor</code> property to <code>appHighlight</code> because that's now the color property binding name.</p><code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (renamed to match directive selector)" region="color-2" ng-version="7.0.0"><div style="display:none">@<a href="api/core/Input" class="code-anchor">Input</a>() appHighlight: string;</div><header class="ng-star-inserted">src/app/highlight.directive.ts (renamed to match directive selector)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (renamed to match directive selector)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">()</span><span class="pln"> appHighlight</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span></code>
    </pre></aio-code></code-example><p translation-result="on">这可不好。因为 <code>appHighlight</code> 是一个糟糕的属性名，而且不能反映该属性的意图。</p><p translation-origin="off">This is disagreeable. The word, <code>appHighlight</code>, is a terrible property name and it doesn't convey the property's intent.</p><a id="input-alias"></a><h3 id="bind-to-an-input-alias" translation-result="on">绑定到 <em>@Input</em> 别名<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#bind-to-an-input-alias"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="bind-to-an-input-alias">Bind to an <em>@Input</em> alias<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#bind-to-an-input-alias"><i class="material-icons">link</i></a></h3><p translation-result="on">幸运的是，你可以随意命名该指令的属性，并且<strong>给它指定一个用于绑定的别名</strong>。</p><p translation-origin="off">Fortunately you can name the directive property whatever you want <em>and</em> <strong><em>alias it</em></strong> for binding purposes.</p><p translation-result="on">恢复原始属性名，并在 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 的参数中把该选择器指定为别名。</p><p translation-origin="off">Restore the original property name and specify the selector as the alias in the argument to <code>@<a href="api/core/Input" class="code-anchor">Input</a></code>.</p><code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" header="src/app/highlight.directive.ts (color property with alias)" region="color" ng-version="7.0.0"><div style="display:none">@<a href="api/core/Input" class="code-anchor">Input</a>('appHighlight') highlightColor: string;</div><header class="ng-star-inserted">src/app/highlight.directive.ts (color property with alias)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (color property with alias)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">(</span><span class="str">'appHighlight'</span><span class="pun">)</span><span class="pln"> highlightColor</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span></code>
    </pre></aio-code></code-example><p translation-result="on">在指令内部，该属性叫 <code>highlightColor</code>，在外部，你绑定到它地方，它叫 <code>appHighlight</code>。</p><p translation-origin="off"><em>Inside</em> the directive the property is known as <code>highlightColor</code>. <em>Outside</em> the directive, where you bind to it, it's known as <code>appHighlight</code>.</p><p translation-result="on">这是最好的结果：理想的内部属性名，理想的绑定语法：</p><p translation-origin="off">You get the best of both worlds: the property name you want and the binding syntax you want:</p><code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (color)" region="color" ng-version="7.0.0"><div style="display:none">&lt;p [appHighlight]="color"&gt;Highlight me!&lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html (color)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html (color)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p</span><span class="pln"> [</span><span class="atn">appHighlight</span><span class="pln">]</span><span class="pun">=</span><span class="atv">"color"</span><span class="tag">&gt;</span><span class="pln">Highlight me!</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">现在，你通过别名绑定到了 <code>highlightColor</code> 属性，并修改 <code>onMouseEnter()</code> 方法来使用它。 如果有人忘了绑定到 <code>appHighlightColor</code>，那就用红色进行高亮。</p><p translation-origin="off">Now that you're binding via the alias to the <code>highlightColor</code>, modify the <code>onMouseEnter()</code> method to use that property. If someone neglects to bind to <code>appHighlightColor</code>, highlight the host element in red:</p><code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" header="src/app/highlight.directive.ts (mouse enter)" region="mouse-enter" ng-version="7.0.0"><div style="display:none">@<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseenter') onMouseEnter() { this.highlight(this.highlightColor || 'red'); }</div><header class="ng-star-inserted">src/app/highlight.directive.ts (mouse enter)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (mouse enter)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/HostListener" class="code-anchor"><span class="lit">HostListener</span></a><span class="pun">(</span><span class="str">'mouseenter'</span><span class="pun">)</span><span class="pln"> onMouseEnter</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlight</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlightColor </span><span class="pun">||</span><span class="pln"> </span><span class="str">'red'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">这是最终版本的指令类。</p><p translation-origin="off">Here's the latest version of the directive class.</p><code-example path="attribute-directives/src/app/highlight.directive.3.ts" linenums="false" header="src/app/highlight.directive.ts (excerpt)" ng-version="7.0.0"><div style="display:none">import { <a href="api/core/Directive" class="code-anchor">Directive</a>, <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>, <a href="api/core/HostListener" class="code-anchor">HostListener</a>, <a href="api/core/Input" class="code-anchor">Input</a> } from '@angular/core'; @<a href="api/core/Directive" class="code-anchor">Directive</a>({ selector: '[appHighlight]' }) export class HighlightDirective { constructor(private el: <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>) { } @<a href="api/core/Input" class="code-anchor">Input</a>('appHighlight') highlightColor: string; @<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseenter') onMouseEnter() { this.highlight(this.highlightColor || 'red'); } @<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseleave') onMouseLeave() { this.highlight(null); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; } }</div><header class="ng-star-inserted">src/app/highlight.directive.ts (excerpt)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (excerpt)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Directive" class="code-anchor"><span class="typ">Directive</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/HostListener" class="code-anchor"><span class="typ">HostListener</span></a><span class="pun">,</span><span class="pln"> </span><a href="api/core/Input" class="code-anchor"><span class="typ">Input</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Directive" class="code-anchor"><span class="lit">Directive</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'[appHighlight]'</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">HighlightDirective</span><span class="pln"> </span><span class="pun">{</span><span class="pln">

  </span><span class="kwd">constructor</span><span class="pun">(</span><span class="kwd">private</span><span class="pln"> el</span><span class="pun">:</span><span class="pln"> </span><a href="api/core/ElementRef" class="code-anchor"><span class="typ">ElementRef</span></a><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

  </span><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">(</span><span class="str">'appHighlight'</span><span class="pun">)</span><span class="pln"> highlightColor</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span><span class="pln">

  </span><span class="lit">@</span><a href="api/core/HostListener" class="code-anchor"><span class="lit">HostListener</span></a><span class="pun">(</span><span class="str">'mouseenter'</span><span class="pun">)</span><span class="pln"> onMouseEnter</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlight</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlightColor </span><span class="pun">||</span><span class="pln"> </span><span class="str">'red'</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="lit">@</span><a href="api/core/HostListener" class="code-anchor"><span class="lit">HostListener</span></a><span class="pun">(</span><span class="str">'mouseleave'</span><span class="pun">)</span><span class="pln"> onMouseLeave</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlight</span><span class="pun">(</span><span class="kwd">null</span><span class="pun">);</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">

  </span><span class="kwd">private</span><span class="pln"> highlight</span><span class="pun">(</span><span class="pln">color</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">)</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">el</span><span class="pun">.</span><span class="pln">nativeElement</span><span class="pun">.</span><span class="pln">style</span><span class="pun">.</span><span class="pln">backgroundColor </span><span class="pun">=</span><span class="pln"> color</span><span class="pun">;</span><span class="pln">
  </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><h2 id="write-a-harness-to-try-it" translation-result="on">写个测试程序试验下<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#write-a-harness-to-try-it"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="write-a-harness-to-try-it">Write a harness to try it<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#write-a-harness-to-try-it"><i class="material-icons">link</i></a></h2><p translation-result="on">凭空想象该指令如何工作可不容易。 在本节，你将把 <code>AppComponent</code> 改成一个测试程序，它让你可以通过单选按钮来选取高亮颜色，并且把你选取的颜色绑定到指令中。</p><p translation-origin="off">It may be difficult to imagine how this directive actually works. In this section, you'll turn <code>AppComponent</code> into a harness that lets you pick the highlight color with a radio button and bind your color choice to the directive.</p><p translation-result="on">把 <code>app.component.html</code> 修改成这样：</p><p translation-origin="off">Update <code>app.component.html</code> as follows:</p><code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (v2)" region="v2" ng-version="7.0.0"><div style="display:none">&lt;h1&gt;My First <a href="api/core/Attribute" class="code-anchor">Attribute</a> <a href="api/core/Directive" class="code-anchor">Directive</a>&lt;/h1&gt; &lt;h4&gt;Pick <a href="api/router/RouterLinkWithHref" class="code-anchor">a</a> highlight color&lt;/h4&gt; &lt;div&gt; &lt;input type="radio" name="colors" (click)="color='lightgreen'"&gt;Green &lt;input type="radio" name="colors" (click)="color='yellow'"&gt;Yellow &lt;input type="radio" name="colors" (click)="color='cyan'"&gt;Cyan &lt;/div&gt; &lt;p [appHighlight]="color"&gt;Highlight me!&lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html (v2)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html (v2)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;h1&gt;</span><span class="pln">My First </span><a href="api/core/Attribute" class="code-anchor"><span class="pln">Attribute</span></a><span class="pln"> </span><a href="api/core/Directive" class="code-anchor"><span class="pln">Directive</span></a><span class="tag">&lt;/h1&gt;</span><span class="pln">

</span><span class="tag">&lt;h4&gt;</span><span class="pln">Pick </span><a href="api/router/RouterLinkWithHref" class="code-anchor"><span class="pln">a</span></a><span class="pln"> highlight color</span><span class="tag">&lt;/h4&gt;</span><span class="pln">
</span><span class="tag">&lt;div&gt;</span><span class="pln">
  </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"colors"</span><span class="pln"> (</span><span class="atn">click</span><span class="pln">)</span><span class="pun">=</span><span class="atv">"color='lightgreen'"</span><span class="tag">&gt;</span><span class="pln">Green
  </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"colors"</span><span class="pln"> (</span><span class="atn">click</span><span class="pln">)</span><span class="pun">=</span><span class="atv">"color='yellow'"</span><span class="tag">&gt;</span><span class="pln">Yellow
  </span><span class="tag">&lt;input</span><span class="pln"> </span><span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span><span class="pln"> </span><span class="atn">name</span><span class="pun">=</span><span class="atv">"colors"</span><span class="pln"> (</span><span class="atn">click</span><span class="pln">)</span><span class="pun">=</span><span class="atv">"color='cyan'"</span><span class="tag">&gt;</span><span class="pln">Cyan
</span><span class="tag">&lt;/div&gt;</span><span class="pln">
</span><span class="tag">&lt;p</span><span class="pln"> [</span><span class="atn">appHighlight</span><span class="pln">]</span><span class="pun">=</span><span class="atv">"color"</span><span class="tag">&gt;</span><span class="pln">Highlight me!</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">修改 <code>AppComponent.color</code>，让它不再有初始值。</p><p translation-origin="off">Revise the <code>AppComponent.color</code> so that it has no initial value.</p><code-example path="attribute-directives/src/app/app.component.ts" linenums="false" header="src/app/app.component.ts (class)" region="class" ng-version="7.0.0"><div style="display:none">export class AppComponent { color: string; }</div><header class="ng-star-inserted">src/app/app.component.ts (class)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.ts (class)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AppComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  color</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">下面是测试程序和指令的动图。</p><p translation-origin="off">Here are the harness and directive in action.</p><figure><img src="generated/images/guide/attribute-directives/highlight-directive-v2-anim.gif" alt="Highlight v.2" width="432" height="172"></figure><a id="second-property"></a><h2 id="bind-to-a-second-property" translation-result="on">绑定到第二个属性<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#bind-to-a-second-property"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="bind-to-a-second-property">Bind to a second property<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#bind-to-a-second-property"><i class="material-icons">link</i></a></h2><p translation-result="on">本例的指令只有一个可定制属性，真实的应用通常需要更多。</p><p translation-origin="off">This highlight directive has a single customizable property. In a real app, it may need more.</p><p translation-result="on">目前，默认颜色（它在用户选取了高亮颜色之前一直有效）被硬编码为红色。应该允许模板的开发者设置默认颜色。</p><p translation-origin="off">At the moment, the default color—the color that prevails until the user picks a highlight color—is hard-coded as "red". Let the template developer set the default color.</p><p translation-result="on">把第二个名叫 <code>defaultColor</code> 的<strong>输入</strong>属性添加到 <code>HighlightDirective</code> 中：</p><p translation-origin="off">Add a second <strong>input</strong> property to <code>HighlightDirective</code> called <code>defaultColor</code>:</p><code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" header="src/app/highlight.directive.ts (defaultColor)" region="defaultColor" ng-version="7.0.0"><div style="display:none">@<a href="api/core/Input" class="code-anchor">Input</a>() defaultColor: string;</div><header class="ng-star-inserted">src/app/highlight.directive.ts (defaultColor)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (defaultColor)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">()</span><span class="pln"> defaultColor</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span></code>
    </pre></aio-code></code-example><p translation-result="on">修改该指令的 <code>onMouseEnter</code>，让它首先尝试使用 <code>highlightColor</code> 进行高亮，然后用 <code>defaultColor</code>，如果它们都没有指定，那就用红色作为后备。</p><p translation-origin="off">Revise the directive's <code>onMouseEnter</code> so that it first tries to highlight with the <code>highlightColor</code>, then with the <code>defaultColor</code>, and falls back to "red" if both properties are undefined.</p><code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" header="src/app/highlight.directive.ts (mouse-enter)" region="mouse-enter" ng-version="7.0.0"><div style="display:none">@<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseenter') onMouseEnter() { this.highlight(this.highlightColor || this.defaultColor || 'red'); }</div><header class="ng-star-inserted">src/app/highlight.directive.ts (mouse-enter)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (mouse-enter)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/HostListener" class="code-anchor"><span class="lit">HostListener</span></a><span class="pun">(</span><span class="str">'mouseenter'</span><span class="pun">)</span><span class="pln"> onMouseEnter</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlight</span><span class="pun">(</span><span class="kwd">this</span><span class="pun">.</span><span class="pln">highlightColor </span><span class="pun">||</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="pln">defaultColor </span><span class="pun">||</span><span class="pln"> </span><span class="str">'red'</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></code-example><p translation-result="on">当已经绑定过 <code>appHighlight</code> 属性时，要如何绑定到第二个属性呢？</p><p translation-origin="off">How do you bind to a second property when you're already binding to the <code>appHighlight</code> attribute name?</p><p translation-result="on">像组件一样，你也可以绑定到指令的很多属性，只要把它们依次写在模板中就行了。 开发者可以绑定到 <code>AppComponent.color</code>，并且用紫罗兰色作为默认颜色，代码如下：</p><p translation-origin="off">As with components, you can add as many directive property bindings as you need by stringing them along in the template. The developer should be able to write the following template HTML to both bind to the <code>AppComponent.color</code> and fall back to "violet" as the default color.</p><code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (defaultColor)" region="defaultColor" ng-version="7.0.0"><div style="display:none">&lt;p [appHighlight]="color" defaultColor="violet"&gt; Highlight me too! &lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html (defaultColor)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html (defaultColor)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p</span><span class="pln"> [</span><span class="atn">appHighlight</span><span class="pln">]</span><span class="pun">=</span><span class="atv">"color"</span><span class="pln"> </span><span class="atn">defaultColor</span><span class="pun">=</span><span class="atv">"violet"</span><span class="tag">&gt;</span><span class="pln">
  Highlight me too!
</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><p translation-result="on">Angular 之所以知道 <code>defaultColor</code> 绑定属于 <code>HighlightDirective</code>，是因为你已经通过 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 装饰器把它设置成了<em>公共</em>属性。</p><p translation-origin="off">Angular knows that the <code>defaultColor</code> binding belongs to the <code>HighlightDirective</code> because you made it <em>public</em> with the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator.</p><p translation-result="on">当这些代码完成时，测试程序工作时的动图如下：</p><p translation-origin="off">Here's how the harness should work when you're done coding.</p><figure><img src="generated/images/guide/attribute-directives/highlight-directive-final-anim.gif" alt="Final Highlight" width="440" height="212"></figure><h2 id="summary" translation-result="on">小结<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#summary"><i class="material-icons">link</i></a></h2><h2 translation-origin="off" id="summary">Summary<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#summary"><i class="material-icons">link</i></a></h2><p translation-result="on">本章介绍了如何：</p><p translation-origin="off">This page covered how to:</p><ul><li><p translation-result="on"><a href="guide/attribute-directives#write-directive">构建一个<strong>属性型指令</strong></a>，它用于修改一个元素的行为。</p><p translation-origin="off"><a href="guide/attribute-directives#write-directive">Build an <strong>attribute directive</strong></a> that modifies the behavior of an element.</p></li><li><p translation-result="on"><a href="guide/attribute-directives#apply-directive">把一个指令应用到</a>模板中的某个元素上。</p><p translation-origin="off"><a href="guide/attribute-directives#apply-directive">Apply the directive</a> to an element in a template.</p></li><li><p translation-result="on"><a href="guide/attribute-directives#respond-to-user">响应<strong>事件</strong></a>以改变指令的行为。</p><p translation-origin="off"><a href="guide/attribute-directives#respond-to-user">Respond to <strong>events</strong></a> that change the directive's behavior.</p></li><li><p translation-result="on"><a href="guide/attribute-directives#bindings">把值<strong>绑定</strong>到指令中</a>。</p><p translation-origin="off"><a href="guide/attribute-directives#bindings"><strong>Bind</strong> values to the directive</a>.</p></li></ul><p translation-result="on">最终的源码如下：</p><p translation-origin="off">The final source code follows:</p><code-tabs ng-version="7.0.0"><div style="display:none"><code-pane header="app/app.component.ts" path="attribute-directives/src/app/app.component.ts">import { <a href="api/core/Component" class="code-anchor">Component</a> } from '@angular/core'; @<a href="api/core/Component" class="code-anchor">Component</a>({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent { color: string; }</code-pane><code-pane header="app/app.component.html" path="attribute-directives/src/app/app.component.html">&lt;h1&gt;My First <a href="api/core/Attribute" class="code-anchor">Attribute</a> <a href="api/core/Directive" class="code-anchor">Directive</a>&lt;/h1&gt; &lt;h4&gt;Pick <a href="api/router/RouterLinkWithHref" class="code-anchor">a</a> highlight color&lt;/h4&gt; &lt;div&gt; &lt;input type="radio" name="colors" (click)="color='lightgreen'"&gt;Green &lt;input type="radio" name="colors" (click)="color='yellow'"&gt;Yellow &lt;input type="radio" name="colors" (click)="color='cyan'"&gt;Cyan &lt;/div&gt; &lt;p [appHighlight]="color"&gt;Highlight me!&lt;/p&gt; &lt;p [appHighlight]="color" defaultColor="violet"&gt; Highlight me too! &lt;/p&gt;</code-pane><code-pane header="app/highlight.directive.ts" path="attribute-directives/src/app/highlight.directive.ts">/* tslint:disable:member-ordering */ import { <a href="api/core/Directive" class="code-anchor">Directive</a>, <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>, <a href="api/core/HostListener" class="code-anchor">HostListener</a>, <a href="api/core/Input" class="code-anchor">Input</a> } from '@angular/core'; @<a href="api/core/Directive" class="code-anchor">Directive</a>({ selector: '[appHighlight]' }) export class HighlightDirective { constructor(private el: <a href="api/core/ElementRef" class="code-anchor">ElementRef</a>) { } @<a href="api/core/Input" class="code-anchor">Input</a>() defaultColor: string; @<a href="api/core/Input" class="code-anchor">Input</a>('appHighlight') highlightColor: string; @<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseenter') onMouseEnter() { this.highlight(this.highlightColor || this.defaultColor || 'red'); } @<a href="api/core/HostListener" class="code-anchor">HostListener</a>('mouseleave') onMouseLeave() { this.highlight(null); } private highlight(color: string) { this.el.nativeElement.style.backgroundColor = color; } }</code-pane><code-pane header="app/app.module.ts" path="attribute-directives/src/app/app.module.ts">import { <a href="api/core/NgModule" class="code-anchor">NgModule</a> } from '@angular/core'; import { <a href="api/platform-browser/BrowserModule" class="code-anchor">BrowserModule</a> } from '@angular/platform-browser'; import { AppComponent } from './app.component'; import { HighlightDirective } from './highlight.directive'; @<a href="api/core/NgModule" class="code-anchor">NgModule</a>({ <a href="api/core/NgModule#imports" class="code-anchor">imports</a>: [ <a href="api/platform-browser/BrowserModule" class="code-anchor">BrowserModule</a> ], <a href="api/core/NgModule#declarations" class="code-anchor">declarations</a>: [ AppComponent, HighlightDirective ], <a href="api/core/NgModule#bootstrap" class="code-anchor">bootstrap</a>: [ AppComponent ] }) export class AppModule { }</code-pane><code-pane header="main.ts" path="attribute-directives/src/main.ts">import { <a href="api/core/enableProdMode" class="code-anchor">enableProdMode</a> } from '@angular/core'; import { <a href="api/platform-browser-dynamic/platformBrowserDynamic" class="code-anchor">platformBrowserDynamic</a> } from '@angular/platform-browser-dynamic'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; if (environment.production) { <a href="api/core/enableProdMode" class="code-anchor">enableProdMode</a>(); } <a href="api/platform-browser-dynamic/platformBrowserDynamic" class="code-anchor">platformBrowserDynamic</a>().bootstrapModule(AppModule);</code-pane><code-pane header="index.html" path="attribute-directives/src/index.html">&lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;title&gt;<a href="api/core/Attribute" class="code-anchor">Attribute</a> Directives&lt;/title&gt; &lt;base <a href="api/router/RouterLinkWithHref#href" class="code-anchor">href</a>="/"&gt; &lt;meta name="viewport" content="width=device-width, initial-scale=1"&gt; &lt;/head&gt; &lt;body&gt; &lt;app-root&gt;&lt;/app-root&gt; &lt;/body&gt; &lt;/html&gt;</code-pane></div><mat-card class="mat-card"><mat-tab-group class="code-tab-group mat-tab-group mat-primary" disableripple=""><mat-tab-header class="mat-tab-header mat-tab-header-pagination-controls-enabled"><div aria-hidden="true" class="mat-tab-header-pagination mat-tab-header-pagination-before mat-elevation-z4 mat-ripple mat-tab-header-pagination-disabled" mat-ripple=""><div class="mat-tab-header-pagination-chevron"></div></div><div class="mat-tab-label-container"><div class="mat-tab-list" role="tablist" style="transform:translateX(0)"><div class="mat-tab-labels"><div cdkmonitorelementfocus="" class="mat-tab-label mat-ripple mat-tab-label-active ng-star-inserted" mat-ripple="" mattablabelwrapper="" role="tab" id="mat-tab-label-0-0" tabindex="0" aria-posinset="1" aria-setsize="6" aria-controls="mat-tab-content-0-0" aria-selected="true" aria-disabled="false"><div class="mat-tab-label-content"><span class="ng-star-inserted">app/app.component.ts</span></div></div><div cdkmonitorelementfocus="" class="mat-tab-label mat-ripple ng-star-inserted" mat-ripple="" mattablabelwrapper="" role="tab" id="mat-tab-label-0-1" tabindex="-1" aria-posinset="2" aria-setsize="6" aria-controls="mat-tab-content-0-1" aria-selected="false" aria-disabled="false"><div class="mat-tab-label-content"><span class="ng-star-inserted">app/app.component.html</span></div></div><div cdkmonitorelementfocus="" class="mat-tab-label mat-ripple ng-star-inserted" mat-ripple="" mattablabelwrapper="" role="tab" id="mat-tab-label-0-2" tabindex="-1" aria-posinset="3" aria-setsize="6" aria-controls="mat-tab-content-0-2" aria-selected="false" aria-disabled="false"><div class="mat-tab-label-content"><span class="ng-star-inserted">app/highlight.directive.ts</span></div></div><div cdkmonitorelementfocus="" class="mat-tab-label mat-ripple ng-star-inserted" mat-ripple="" mattablabelwrapper="" role="tab" id="mat-tab-label-0-3" tabindex="-1" aria-posinset="4" aria-setsize="6" aria-controls="mat-tab-content-0-3" aria-selected="false" aria-disabled="false"><div class="mat-tab-label-content"><span class="ng-star-inserted">app/app.module.ts</span></div></div><div cdkmonitorelementfocus="" class="mat-tab-label mat-ripple ng-star-inserted" mat-ripple="" mattablabelwrapper="" role="tab" id="mat-tab-label-0-4" tabindex="-1" aria-posinset="5" aria-setsize="6" aria-controls="mat-tab-content-0-4" aria-selected="false" aria-disabled="false"><div class="mat-tab-label-content"><span class="ng-star-inserted">main.ts</span></div></div><div cdkmonitorelementfocus="" class="mat-tab-label mat-ripple ng-star-inserted" mat-ripple="" mattablabelwrapper="" role="tab" id="mat-tab-label-0-5" tabindex="-1" aria-posinset="6" aria-setsize="6" aria-controls="mat-tab-content-0-5" aria-selected="false" aria-disabled="false"><div class="mat-tab-label-content"><span class="ng-star-inserted">index.html</span></div></div></div><mat-ink-bar class="mat-ink-bar" style="visibility:visible;left:0;width:187px"></mat-ink-bar></div></div><div aria-hidden="true" class="mat-tab-header-pagination mat-tab-header-pagination-after mat-elevation-z4 mat-ripple" mat-ripple=""><div class="mat-tab-header-pagination-chevron"></div></div></mat-tab-header><div class="mat-tab-body-wrapper"><mat-tab-body class="mat-tab-body ng-tns-c12-2 mat-tab-body-active ng-star-inserted" role="tabpanel" id="mat-tab-content-0-0" aria-labelledby="mat-tab-label-0-0"><div class="mat-tab-body-content ng-trigger ng-trigger-translateTab" style="transform:none"><aio-code class="ng-star-inserted" style=""><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from app/app.component.ts">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="kwd">import</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><a href="api/core/Component" class="code-anchor"><span class="typ">Component</span></a><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="str">'@angular/core'</span><span class="pun">;</span><span class="pln">

</span><span class="lit">@</span><a href="api/core/Component" class="code-anchor"><span class="lit">Component</span></a><span class="pun">({</span><span class="pln">
  selector</span><span class="pun">:</span><span class="pln"> </span><span class="str">'app-root'</span><span class="pun">,</span><span class="pln">
  templateUrl</span><span class="pun">:</span><span class="pln"> </span><span class="str">'./app.component.html'</span><span class="pln">
</span><span class="pun">})</span><span class="pln">
</span><span class="kwd">export</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AppComponent</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
  color</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span><span class="pln">
</span><span class="pun">}</span></code>
    </pre></aio-code></div></mat-tab-body><mat-tab-body class="mat-tab-body ng-tns-c12-3 ng-star-inserted" role="tabpanel" id="mat-tab-content-0-1" aria-labelledby="mat-tab-label-0-1"><div class="mat-tab-body-content ng-trigger ng-trigger-translateTab" style="transform:translate3d(100%,0,0);min-height:1px"></div></mat-tab-body><mat-tab-body class="mat-tab-body ng-tns-c12-4 ng-star-inserted" role="tabpanel" id="mat-tab-content-0-2" aria-labelledby="mat-tab-label-0-2"><div class="mat-tab-body-content ng-trigger ng-trigger-translateTab" style="transform:translate3d(100%,0,0);min-height:1px"></div></mat-tab-body><mat-tab-body class="mat-tab-body ng-tns-c12-5 ng-star-inserted" role="tabpanel" id="mat-tab-content-0-3" aria-labelledby="mat-tab-label-0-3"><div class="mat-tab-body-content ng-trigger ng-trigger-translateTab" style="transform:translate3d(100%,0,0);min-height:1px"></div></mat-tab-body><mat-tab-body class="mat-tab-body ng-tns-c12-6 ng-star-inserted" role="tabpanel" id="mat-tab-content-0-4" aria-labelledby="mat-tab-label-0-4"><div class="mat-tab-body-content ng-trigger ng-trigger-translateTab" style="transform:translate3d(100%,0,0);min-height:1px"></div></mat-tab-body><mat-tab-body class="mat-tab-body ng-tns-c12-7 ng-star-inserted" role="tabpanel" id="mat-tab-content-0-5" aria-labelledby="mat-tab-label-0-5"><div class="mat-tab-body-content ng-trigger ng-trigger-translateTab" style="transform:translate3d(100%,0,0);min-height:1px"></div></mat-tab-body></div></mat-tab-group></mat-card></code-tabs><p translation-result="on">你还可以体验和下载<live-example title="属性型指令范例" ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/attribute-directives/stackblitz.html" title="属性型指令范例">属性型指令范例</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/attribute-directives/attribute-directives.zip">下载范例</a></span></span></span></live-example>.</p><p translation-origin="off">You can also experience and download the<live-example title="Attribute Directive example" ng-version="7.0.0"><span style="display:none"></span><span><span class="ng-star-inserted"><a target="_blank" href="generated/live-examples/attribute-directives/stackblitz.html" title="Attribute Directive example">Attribute Directive example</a><span class="ng-star-inserted"> / <a download="" title="下载范例" href="generated/zips/attribute-directives/attribute-directives.zip">下载范例</a></span></span></span></live-example>.</p><a id="why-input"></a><h3 id="appendix-why-add-input" translation-result="on">附录：为什么要加<em>@Input</em>？<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#appendix-why-add-input"><i class="material-icons">link</i></a></h3><h3 translation-origin="off" id="appendix-why-add-input">Appendix: Why add <em>@Input</em>?<a title="Link to this heading" class="header-link" aria-hidden="true" href="guide/attribute-directives#appendix-why-add-input"><i class="material-icons">link</i></a></h3><p translation-result="on">在这个例子中 <code>hightlightColor</code> 是 <code>HighlightDirective</code> 的一个<strong><em>输入型</em></strong>属性。你见过它没有用别名时的代码：</p><p translation-origin="off">In this demo, the <code>highlightColor</code> property is an <strong><em>input</em></strong> property of the <code>HighlightDirective</code>. You've seen it applied without an alias:</p><code-example path="attribute-directives/src/app/highlight.directive.2.ts" linenums="false" header="src/app/highlight.directive.ts (color)" region="color" ng-version="7.0.0"><div style="display:none">@<a href="api/core/Input" class="code-anchor">Input</a>() highlightColor: string;</div><header class="ng-star-inserted">src/app/highlight.directive.ts (color)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (color)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">()</span><span class="pln"> highlightColor</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span></code>
    </pre></aio-code></code-example><p translation-result="on">也见过用别名时的代码：</p><p translation-origin="off">You've seen it with an alias:</p><code-example path="attribute-directives/src/app/highlight.directive.ts" linenums="false" header="src/app/highlight.directive.ts (color)" region="color" ng-version="7.0.0"><div style="display:none">@<a href="api/core/Input" class="code-anchor">Input</a>('appHighlight') highlightColor: string;</div><header class="ng-star-inserted">src/app/highlight.directive.ts (color)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/highlight.directive.ts (color)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="lit">@</span><a href="api/core/Input" class="code-anchor"><span class="lit">Input</span></a><span class="pun">(</span><span class="str">'appHighlight'</span><span class="pun">)</span><span class="pln"> highlightColor</span><span class="pun">:</span><span class="pln"> </span><span class="kwd">string</span><span class="pun">;</span></code>
    </pre></aio-code></code-example><p translation-result="on">无论哪种方式，<code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 装饰器都告诉 Angular，该属性是<em>公共的</em>，并且能被父组件绑定。 如果没有 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code>，Angular 就会拒绝绑定到该属性。</p><p translation-origin="off">Either way, the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator tells Angular that this property is <em>public</em> and available for binding by a parent component. Without <code>@<a href="api/core/Input" class="code-anchor">Input</a></code>, Angular refuses to bind to the property.</p><p translation-result="on">但你以前也曾经把模板 HTML 绑定到组件的属性，而且从来没有用过 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code>。 差异何在？</p><p translation-origin="off">You've bound template HTML to component properties before and never used <code>@<a href="api/core/Input" class="code-anchor">Input</a></code>. What's different?</p><p translation-result="on">差异在于信任度不同。 Angular 把组件的模板看做<em>从属于</em>该组件的。 组件和它的模板默认会相互信任。 这也就是意味着，组件自己的模板可以绑定到组件的<em>任意</em>属性，无论是否使用了 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 装饰器。</p><p translation-origin="off">The difference is a matter of trust. Angular treats a component's template as <em>belonging</em> to the component. The component and its template trust each other implicitly. Therefore, the component's own template may bind to <em>any</em> property of that component, with or without the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator.</p><p translation-result="on">但组件或指令不应该盲目的信任其它组件或指令。 因此组件或指令的属性默认是不能被绑定的。 从 Angular 绑定机制的角度来看，它们是<em>私有</em>的，而当添加了 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 时，Angular 绑定机制才会把它们当成<em>公共</em>的。 只有这样，它们才能被其它组件或属性绑定。</p><p translation-origin="off">But a component or directive shouldn't blindly trust <em>other</em> components and directives. The properties of a component or directive are hidden from binding by default. They are <em>private</em> from an Angular binding perspective. When adorned with the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator, the property becomes <em>public</em> from an Angular binding perspective. Only then can it be bound by some other component or directive.</p><p translation-result="on">你可以根据属性名在绑定中出现的位置来判定是否要加 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code>。</p><p translation-origin="off">You can tell if <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> is needed by the position of the property name in a binding.</p><ul><li><p translation-result="on">当它出现在等号<strong><em>右侧</em></strong>的模板表达式中时，它属于模板所在的组件，不需要 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 装饰器。</p><p translation-origin="off">When it appears in the template expression to the <strong><em>right</em></strong> of the equals (=), it belongs to the template's component and does not require the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator.</p></li><li><p translation-result="on">当它出现在等号<strong>左边</strong>的<strong>方括号（[ ]）</strong>中时，该属性属于<em>其它</em>组件或指令，它必须带有 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 装饰器。</p><p translation-origin="off">When it appears in <strong>square brackets</strong> ([ ]) to the <strong>left</strong> of the equals (=), the property belongs to some <em>other</em> component or directive; that property must be adorned with the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator.</p></li></ul><p translation-result="on">试用此原理分析下列范例：</p><p translation-origin="off">Now apply that reasoning to the following example:</p><code-example path="attribute-directives/src/app/app.component.html" linenums="false" header="src/app/app.component.html (color)" region="color" ng-version="7.0.0"><div style="display:none">&lt;p [appHighlight]="color"&gt;Highlight me!&lt;/p&gt;</div><header class="ng-star-inserted">src/app/app.component.html (color)</header><aio-code class="headed-code"><pre class="prettyprint lang-">      <button class="material-icons copy-button no-print ng-star-inserted" title="Copy code snippet" aria-label="Copy code snippet from src/app/app.component.html (color)">
        <span aria-hidden="true">content_copy</span>
      </button>
      <code class="animated fadeIn"><span class="tag">&lt;p</span><span class="pln"> [</span><span class="atn">appHighlight</span><span class="pln">]</span><span class="pun">=</span><span class="atv">"color"</span><span class="tag">&gt;</span><span class="pln">Highlight me!</span><span class="tag">&lt;/p&gt;</span></code>
    </pre></aio-code></code-example><ul><li><p translation-result="on"> <code>color</code> 属性位于右侧的绑定表达式中，它属于模板所在的组件。 该模板和组件相互信任。因此 <code>color</code> 不需要 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 装饰器。</p><p translation-origin="off">The <code>color</code> property in the expression on the right belongs to the template's component. The template and its component trust each other. The <code>color</code> property doesn't require the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator.</p></li><li><p translation-result="on"> <code>appHighlight</code> 属性位于左侧，它引用了 <code>HighlightDirective</code> 中一个<em>带别名的</em>属性，它不是模板所属组件的一部分，因此存在信任问题。 所以，该属性必须带 <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> 装饰器。</p><p translation-origin="off">The <code>appHighlight</code> property on the left refers to an <em>aliased</em> property of the <code>HighlightDirective</code>, not a property of the template's component. There are trust issues. Therefore, the directive property must carry the <code>@<a href="api/core/Input" class="code-anchor">Input</a></code> decorator.</p></li></ul></div></div></aio-doc-viewer></main></mat-sidenav-content></mat-sidenav-container><div class="toc-container no-print ng-star-inserted"><aio-lazy-ce selector="aio-toc"><aio-toc ng-version="7.0.0"><div class="toc-inner no-print collapsed ng-star-inserted"><ul class="toc-list"><li title="属性型指令link" class="h1 ng-star-inserted active"><a href="guide/attribute-directives#attribute-directives">属性型指令</a></li><li title="指令概览link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#directives-overview">指令概览</a></li><li title="创建一个简单的属性型指令link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#build-a-simple-attribute-directive">创建一个简单的属性型指令</a></li><li title="编写指令代码link" class="h3 ng-star-inserted"><a href="guide/attribute-directives#write-the-directive-code">编写指令代码</a></li><li title="使用属性型指令link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#apply-the-attribute-directive">使用属性型指令</a></li><li title="响应用户引发的事件link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#respond-to-user-initiated-events">响应用户引发的事件</a></li><li title="使用 @Input 数据绑定向指令传递值link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#pass-values-into-the-directive-with-an-input-data-binding">使用 <code>@Input</code> 数据绑定向指令传递值</a></li><li title="绑定到 @Input 属性link" class="h3 ng-star-inserted"><a href="guide/attribute-directives#binding-to-an-input-property">绑定到 <em>@Input</em> 属性</a></li><li title="绑定到 @Input 别名link" class="h3 ng-star-inserted"><a href="guide/attribute-directives#bind-to-an-input-alias">绑定到 <em>@Input</em> 别名</a></li><li title="写个测试程序试验下link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#write-a-harness-to-try-it">写个测试程序试验下</a></li><li title="绑定到第二个属性link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#bind-to-a-second-property">绑定到第二个属性</a></li><li title="小结link" class="h2 ng-star-inserted"><a href="guide/attribute-directives#summary">小结</a></li><li title="附录：为什么要加@Input？link" class="h3 ng-star-inserted"><a href="guide/attribute-directives#appendix-why-add-input">附录：为什么要加<em>@Input</em>？</a></li></ul></div></aio-toc></aio-lazy-ce></div><footer class="no-print"><aio-footer><div class="grid-fluid"><div class="footer-block ng-star-inserted"><h3>资源</h3><ul><li class="ng-star-inserted"><a class="link" href="about" title="Angular 贡献者。">关于</a></li><li class="ng-star-inserted"><a class="link" href="resources" title="网络上的 Angular 工具、培训、博客等">资源列表</a></li><li class="ng-star-inserted"><a class="link" href="presskit" title="我们的联系方式、LOGO 和品牌">宣传资料</a></li><li class="ng-star-inserted"><a class="link" href="https://blog.angular.io/" title="Angular 官方博客">博客</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>帮助</h3><ul><li class="ng-star-inserted"><a class="link" href="https://stackoverflow.com/questions/tagged/angular" title="Stack Overflow: 这里的社区会回答你关于 Angular 的技术问题">Stack Overflow</a></li><li class="ng-star-inserted"><a class="link" href="https://gitter.im/angular/angular" title="和老鸟聊 Angular">Gitter</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/angular/issues" title="在 github 上报告问题和建议。">报告问题</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/code-of-conduct/blob/master/CODE_OF_CONDUCT.md" title="让我们彼此尊重">行为规范</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>社区</h3><ul><li class="ng-star-inserted"><a class="link" href="events" title="Post issues and suggestions on github.">活动</a></li><li class="ng-star-inserted"><a class="link" href="http://www.meetup.com/topics/angularjs/" title="参加聚会，向别的开发人员学习">聚会</a></li><li class="ng-star-inserted"><a class="link" href="https://twitter.com/angular" title="Twitter">Twitter</a></li><li class="ng-star-inserted"><a class="link" href="https://github.com/angular/angular" title="GitHub">GitHub</a></li><li class="ng-star-inserted"><a class="link" href="contribute" title="向 Angular 做贡献">做贡献</a></li></ul></div><div class="footer-block ng-star-inserted"><h3>多语言</h3><ul><li class="ng-star-inserted"><a class="link" href="https://angular.io/" title="English Version.">English Version</a></li><li class="ng-star-inserted"><a class="link" href="https://angular.jp/" title="日本語版">日本語版</a></li><li class="ng-star-inserted"><a class="link" href="https://angular.kr/" title="한국어">한국어</a></li></ul></div></div><p>Super-powered by Google ©2010-2019. 代码授权方式：<a href="license" title="License text">MIT-style License</a>. 文档授权方式：<a href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.</p><p>当前版本：8.0.0-build.95+sha.43aadf1.</p></aio-footer></footer><mat-icon class="cdk-visually-hidden mat-icon material-icons ng-star-inserted" role="img" aria-hidden="true">&nbsp;</mat-icon></aio-shell><noscript><div class="background-sky hero"></div><section id="intro" style="text-shadow:1px 1px #1976d2"><div class="hero-logo"><img src="assets/images/logos/angular/angular.svg" width="250" height="250" alt="Angular"></div><div class="homepage-container"><div class="hero-headline">一套框架，多种平台<br>移动 &amp; 桌面</div></div></section><h2 style="color:red;margin-top:40px;position:relative;text-align:center;text-shadow:1px 1px #fafafa"><b><i>该网站需要浏览器支持 JavaScript</i></b></h2></noscript><script src="runtime.fa3355727d5250409e08.js"></script><script src="polyfills.a2efc1c1a62312ff1f80.js"></script><script src="main.02884fe4cde5ede2ec4e.js"></script><div class="cdk-live-announcer-element cdk-visually-hidden" aria-atomic="true" aria-live="polite"></div></body></html>